diff options
author | Warner Losh <imp@FreeBSD.org> | 2010-02-18 16:05:09 +0000 |
---|---|---|
committer | Warner Losh <imp@FreeBSD.org> | 2010-02-18 16:05:09 +0000 |
commit | 30c1278f14e353c632e11a4285c9a67216e8be77 (patch) | |
tree | 4f99f2843944fba2058eaabb4b13a09cdea89b84 | |
parent | c0f29c6e1d44b27d1e118443b2df8e0a372c97ac (diff) | |
download | src-30c1278f14e353c632e11a4285c9a67216e8be77.tar.gz src-30c1278f14e353c632e11a4285c9a67216e8be77.zip |
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
Notes
Notes:
svn path=/head/; revision=204045
-rw-r--r-- | usr.bin/kdump/kdump.c | 12 |
1 files changed, 9 insertions, 3 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(ss)) + goto invalid; + memcpy(&ss, data, datalen); if (datalen < sizeof(struct sockaddr) || - datalen != ((struct sockaddr *)(data))->sa_len) + datalen != ss.ss_len) goto invalid; - ktrsockaddr((struct sockaddr *)data); + ktrsockaddr((struct sockaddr *)&ss); } else { printf("unknown structure\n"); } |