From: Peter Maydell <[email protected]> If you pass sendto() a NULL buffer, this is usually an error (causing an EFAULT return); however if you pass a 0 length then we should not try to validate the buffer provided. Instead we skip the copying of the user data and possible processing through fd_trans_target_to_host_data, and call the host syscall with NULL, 0.
(unlock_user() permits a NULL buffer pointer for "do nothing" so we don't need to special case the unlock code.) Cc: [email protected] Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3102 Signed-off-by: Peter Maydell <[email protected]> Reviewed-by: Michael Tokarev <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Signed-off-by: Richard Henderson <[email protected]> Message-ID: <[email protected]> (cherry picked from commit 0db2de22fcbf90adafab9d9dd1fc8203c66bfa75) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 737065c28c..93b66bd2d7 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3529,7 +3529,7 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr, socklen_t addrlen) { void *addr; - void *host_msg; + void *host_msg = NULL; void *copy_msg = NULL; abi_long ret; @@ -3537,16 +3537,19 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags, return -TARGET_EINVAL; } - host_msg = lock_user(VERIFY_READ, msg, len, 1); - if (!host_msg) - return -TARGET_EFAULT; - if (fd_trans_target_to_host_data(fd)) { - copy_msg = host_msg; - host_msg = g_malloc(len); - memcpy(host_msg, copy_msg, len); - ret = fd_trans_target_to_host_data(fd)(host_msg, len); - if (ret < 0) { - goto fail; + if (len != 0) { + host_msg = lock_user(VERIFY_READ, msg, len, 1); + if (!host_msg) { + return -TARGET_EFAULT; + } + if (fd_trans_target_to_host_data(fd)) { + copy_msg = host_msg; + host_msg = g_malloc(len); + memcpy(host_msg, copy_msg, len); + ret = fd_trans_target_to_host_data(fd)(host_msg, len); + if (ret < 0) { + goto fail; + } } } if (target_addr) { -- 2.47.3
