From 30c1278f14e353c632e11a4285c9a67216e8be77 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 18 Feb 2010 16:05:09 +0000 Subject: [PATCH] The kdump data stream is an unaligned data stream for stat and sockaddr structures. As such, we have top copy the data structure into a local buffer before we can reference it, otherwise we have unaligned references (these are fixed up automatically on some CPUs, but not on others). We do this unconditionally to make the code easier to read and understand. Submitted by: Grzegorz Bernacki --- usr.bin/kdump/kdump.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index 47b3398bd055..9c86fff189b9 100644 --- a/usr.bin/kdump/kdump.c +++ b/usr.bin/kdump/kdump.c @@ -1328,6 +1328,8 @@ ktrstruct(char *buf, size_t buflen) char *name, *data; size_t namelen, datalen; int i; + struct stat sb; + struct sockaddr_storage ss; for (name = buf, namelen = 0; namelen < buflen && name[namelen] != '\0'; @@ -1348,12 +1350,16 @@ ktrstruct(char *buf, size_t buflen) if (strcmp(name, "stat") == 0) { if (datalen != sizeof(struct stat)) goto invalid; - ktrstat((struct stat *)data); + memcpy(&sb, data, datalen); + ktrstat(&sb); } else if (strcmp(name, "sockaddr") == 0) { - if (datalen < sizeof(struct sockaddr) || - datalen != ((struct sockaddr *)(data))->sa_len) + if (datalen > sizeof(ss)) goto invalid; - ktrsockaddr((struct sockaddr *)data); + memcpy(&ss, data, datalen); + if (datalen < sizeof(struct sockaddr) || + datalen != ss.ss_len) + goto invalid; + ktrsockaddr((struct sockaddr *)&ss); } else { printf("unknown structure\n"); }