diff options
| author | Laszlo Valko <valko@linux.karinthy.hu> | 2003-01-15 07:25:42 -0800 |
|---|---|---|
| committer | David S. Miller <davem@nuts.ninka.net> | 2003-01-15 07:25:42 -0800 |
| commit | d142cd23328e4357d2748cf059ff38511334963f (patch) | |
| tree | e7ac3258f52ca7f8d9a6956cc8e2374518978163 | |
| parent | bb36f487c7943955c73bac7380093deaf7262e76 (diff) | |
[SPARC64]: Handle SO_TIMESTAMP properly in compat recvmsg.
| -rw-r--r-- | arch/sparc64/kernel/sys_sparc32.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 8b51679f8430..1dd8bebcda4e 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -2298,10 +2298,27 @@ static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_up __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type); clen64 = kcmsg32->cmsg_len; - copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg), - clen64 - CMSG_ALIGN(sizeof(*ucmsg))); - clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) + - CMSG32_ALIGN(sizeof(struct cmsghdr32))); + if (kcmsg32->cmsg_level == SOL_SOCKET && + kcmsg32->cmsg_type == SO_TIMESTAMP) { + struct timeval tv; + struct compat_timeval *tv32; + + if (clen64 != CMSG_LEN(sizeof(struct timeval))) { + kfree(workbuf); + goto fail; + } + copy_from_user(&tv, CMSG_DATA(ucmsg), sizeof(tv)); + tv32 = (struct compat_timeval *) CMSG32_DATA(kcmsg32); + tv32->tv_sec = tv.tv_sec; + tv32->tv_usec = tv.tv_usec; + clen32 = sizeof(*tv32) + + CMSG32_ALIGN(sizeof(struct cmsghdr32)); + } else { + copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg), + clen64 - CMSG_ALIGN(sizeof(*ucmsg))); + clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) + + CMSG32_ALIGN(sizeof(struct cmsghdr32))); + } kcmsg32->cmsg_len = clen32; ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64)); |
