[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] linux-user: fix emulation of accept4/getpeernam
From: |
Laurent Vivier |
Subject: |
Re: [Qemu-devel] [PATCH] linux-user: fix emulation of accept4/getpeername/getsockname/recvfrom syscalls |
Date: |
Thu, 14 Feb 2019 10:17:39 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 |
On 07/02/2019 15:51, Andreas Schwab wrote:
> System calls that return a socket address do so by writing the (possibly
> truncated) address into the provided buffer space, but setting the addrlen
> parameter to the actual size of the address. To determine how much to
> copy back to the target memory the emulation needs to remember the old
> value of the addrlen parameter, so that it doesn't write past the buffer
> limits.
>
> Signed-off-by: Andreas Schwab <address@hidden>
Andreas,
could you fix the coding style errors reported by patchew?
Thanks,
Laurent
> ---
> linux-user/syscall.c | 38 ++++++++++++++++++++++----------------
> 1 file changed, 22 insertions(+), 16 deletions(-)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 55fa235a56..90bfda3563 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -2884,7 +2884,7 @@ static abi_long do_sendrecvmmsg(int fd, abi_ulong
> target_msgvec,
> static abi_long do_accept4(int fd, abi_ulong target_addr,
> abi_ulong target_addrlen_addr, int flags)
> {
> - socklen_t addrlen;
> + socklen_t addrlen, ret_addrlen;
> void *addr;
> abi_long ret;
> int host_flags;
> @@ -2908,10 +2908,11 @@ static abi_long do_accept4(int fd, abi_ulong
> target_addr,
>
> addr = alloca(addrlen);
>
> - ret = get_errno(safe_accept4(fd, addr, &addrlen, host_flags));
> + ret_addrlen = addrlen;
> + ret = get_errno(safe_accept4(fd, addr, &ret_addrlen, host_flags));
> if (!is_error(ret)) {
> - host_to_target_sockaddr(target_addr, addr, addrlen);
> - if (put_user_u32(addrlen, target_addrlen_addr))
> + host_to_target_sockaddr(target_addr, addr, MIN(addrlen,
> ret_addrlen));
> + if (put_user_u32(ret_addrlen, target_addrlen_addr))
> ret = -TARGET_EFAULT;
> }
> return ret;
> @@ -2921,7 +2922,7 @@ static abi_long do_accept4(int fd, abi_ulong
> target_addr,
> static abi_long do_getpeername(int fd, abi_ulong target_addr,
> abi_ulong target_addrlen_addr)
> {
> - socklen_t addrlen;
> + socklen_t addrlen, ret_addrlen;
> void *addr;
> abi_long ret;
>
> @@ -2937,10 +2938,11 @@ static abi_long do_getpeername(int fd, abi_ulong
> target_addr,
>
> addr = alloca(addrlen);
>
> - ret = get_errno(getpeername(fd, addr, &addrlen));
> + ret_addrlen = addrlen;
> + ret = get_errno(getpeername(fd, addr, &ret_addrlen));
> if (!is_error(ret)) {
> - host_to_target_sockaddr(target_addr, addr, addrlen);
> - if (put_user_u32(addrlen, target_addrlen_addr))
> + host_to_target_sockaddr(target_addr, addr, MIN(addrlen,
> ret_addrlen));
> + if (put_user_u32(ret_addrlen, target_addrlen_addr))
> ret = -TARGET_EFAULT;
> }
> return ret;
> @@ -2950,7 +2952,7 @@ static abi_long do_getpeername(int fd, abi_ulong
> target_addr,
> static abi_long do_getsockname(int fd, abi_ulong target_addr,
> abi_ulong target_addrlen_addr)
> {
> - socklen_t addrlen;
> + socklen_t addrlen, ret_addrlen;
> void *addr;
> abi_long ret;
>
> @@ -2966,10 +2968,11 @@ static abi_long do_getsockname(int fd, abi_ulong
> target_addr,
>
> addr = alloca(addrlen);
>
> - ret = get_errno(getsockname(fd, addr, &addrlen));
> + ret_addrlen = addrlen;
> + ret = get_errno(getsockname(fd, addr, &ret_addrlen));
> if (!is_error(ret)) {
> - host_to_target_sockaddr(target_addr, addr, addrlen);
> - if (put_user_u32(addrlen, target_addrlen_addr))
> + host_to_target_sockaddr(target_addr, addr, MIN(addrlen,
> ret_addrlen));
> + if (put_user_u32(ret_addrlen, target_addrlen_addr))
> ret = -TARGET_EFAULT;
> }
> return ret;
> @@ -3042,7 +3045,7 @@ static abi_long do_recvfrom(int fd, abi_ulong msg,
> size_t len, int flags,
> abi_ulong target_addr,
> abi_ulong target_addrlen)
> {
> - socklen_t addrlen;
> + socklen_t addrlen, ret_addrlen;
> void *addr;
> void *host_msg;
> abi_long ret;
> @@ -3060,10 +3063,12 @@ static abi_long do_recvfrom(int fd, abi_ulong msg,
> size_t len, int flags,
> goto fail;
> }
> addr = alloca(addrlen);
> + ret_addrlen = addrlen;
> ret = get_errno(safe_recvfrom(fd, host_msg, len, flags,
> - addr, &addrlen));
> + addr, &ret_addrlen));
> } else {
> addr = NULL; /* To keep compiler quiet. */
> + addrlen = 0; /* To keep compiler quiet. */
> ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, NULL, 0));
> }
> if (!is_error(ret)) {
> @@ -3076,8 +3081,9 @@ static abi_long do_recvfrom(int fd, abi_ulong msg,
> size_t len, int flags,
> }
> }
> if (target_addr) {
> - host_to_target_sockaddr(target_addr, addr, addrlen);
> - if (put_user_u32(addrlen, target_addrlen)) {
> + host_to_target_sockaddr(target_addr, addr,
> + MIN(addrlen, ret_addrlen));
> + if (put_user_u32(ret_addrlen, target_addrlen)) {
> ret = -TARGET_EFAULT;
> goto fail;
> }
>