From: Helge Deller <[email protected]> Add handlers for both sockopts which use 64-bit time_t from userspace.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/885 Signed-off-by: Helge Deller <[email protected]> (cherry picked from commit 07c7decaa54a83bd1656b2645074380714b83374) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/linux-user/syscall.c b/linux-user/syscall.c index d2c98b7237..76b655da2b 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2625,7 +2625,8 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, /* These don't just return a single integer */ case TARGET_SO_PEERNAME: goto unimplemented; - case TARGET_SO_RCVTIMEO: { + case TARGET_SO_RCVTIMEO: + case TARGET_SO_RCVTIMEO_NEW: { struct timeval tv; socklen_t tvlen; @@ -2645,11 +2646,17 @@ get_timeout: if (ret < 0) { return ret; } - if (len > sizeof(struct target_timeval)) { - len = sizeof(struct target_timeval); - } - if (copy_to_user_timeval(optval_addr, &tv)) { - return -TARGET_EFAULT; + if (len == sizeof(struct target__kernel_sock_timeval)) { + if (copy_to_user_timeval64(optval_addr, &tv)) { + return -TARGET_EFAULT; + } + } else { + if (len >= sizeof(struct target_timeval)) { + len = sizeof(struct target_timeval); + if (copy_to_user_timeval(optval_addr, &tv)) { + return -TARGET_EFAULT; + } + } } if (put_user_u32(len, optlen)) { return -TARGET_EFAULT; @@ -2657,6 +2664,7 @@ get_timeout: break; } case TARGET_SO_SNDTIMEO: + case TARGET_SO_SNDTIMEO_NEW: optname = SO_SNDTIMEO; goto get_timeout; case TARGET_SO_PEERCRED: { -- 2.47.3
