From: Peter Maydell Date: Tue, 28 Oct 2025 14:20:01 +0000 (+0000) Subject: linux-user: permit sendto() with NULL buf and 0 len X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0db2de22fcbf90adafab9d9dd1fc8203c66bfa75;p=thirdparty%2Fqemu.git linux-user: permit sendto() with NULL buf and 0 len 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: qemu-stable@nongnu.org Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3102 Signed-off-by: Peter Maydell Reviewed-by: Michael Tokarev Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-ID: <20251028142001.3011630-1-peter.maydell@linaro.org> --- diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 8546f48a05..2060e561a2 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3581,7 +3581,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; @@ -3589,16 +3589,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) {