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]> --- linux-user/syscall.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) 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) { -- 2.43.0
