Commit 8f7aeaf6 authored by Aurelien Jarno's avatar Aurelien Jarno
Browse files

linux-user: return EINVAL on incorrect sockaddr



From: Lauro Ramos Venancio <lauro.venancio@gmail.com>

Fixes ltp test accept01

Signed-off-by: default avatarRiku Voipio <riku.voipio@iki.fi>
Signed-off-by: default avatarAurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6479 c046a42c-6fe2-441c-8c8c-71466251a162
parent 8fea3602
Loading
Loading
Loading
Loading
+31 −2
Original line number Diff line number Diff line
@@ -1140,11 +1140,19 @@ static abi_long do_socket(int domain, int type, int protocol)
    return get_errno(socket(domain, type, protocol));
}

/* MAX_SOCK_ADDR from linux/net/socket.c */
#define MAX_SOCK_ADDR	128

/* do_bind() Must return target values and target errnos. */
static abi_long do_bind(int sockfd, abi_ulong target_addr,
                        socklen_t addrlen)
{
    void *addr = alloca(addrlen);
    void *addr;

    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
        return -TARGET_EINVAL;

    addr = alloca(addrlen);

    target_to_host_sockaddr(addr, target_addr, addrlen);
    return get_errno(bind(sockfd, addr, addrlen));
@@ -1154,7 +1162,12 @@ static abi_long do_bind(int sockfd, abi_ulong target_addr,
static abi_long do_connect(int sockfd, abi_ulong target_addr,
                           socklen_t addrlen)
{
    void *addr = alloca(addrlen);
    void *addr;

    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
        return -TARGET_EINVAL;

    addr = alloca(addrlen);

    target_to_host_sockaddr(addr, target_addr, addrlen);
    return get_errno(connect(sockfd, addr, addrlen));
@@ -1226,6 +1239,9 @@ static abi_long do_accept(int fd, abi_ulong target_addr,
    if (get_user_u32(addrlen, target_addrlen_addr))
        return -TARGET_EFAULT;

    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
        return -TARGET_EINVAL;

    addr = alloca(addrlen);

    ret = get_errno(accept(fd, addr, &addrlen));
@@ -1248,6 +1264,9 @@ static abi_long do_getpeername(int fd, abi_ulong target_addr,
    if (get_user_u32(addrlen, target_addrlen_addr))
        return -TARGET_EFAULT;

    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
        return -TARGET_EINVAL;

    addr = alloca(addrlen);

    ret = get_errno(getpeername(fd, addr, &addrlen));
@@ -1273,6 +1292,9 @@ static abi_long do_getsockname(int fd, abi_ulong target_addr,
    if (get_user_u32(addrlen, target_addrlen_addr))
        return -TARGET_EFAULT;

    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
        return -TARGET_EINVAL;

    addr = alloca(addrlen);

    ret = get_errno(getsockname(fd, addr, &addrlen));
@@ -1308,6 +1330,9 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
    void *host_msg;
    abi_long ret;

    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
        return -TARGET_EINVAL;

    host_msg = lock_user(VERIFY_READ, msg, len, 1);
    if (!host_msg)
        return -TARGET_EFAULT;
@@ -1340,6 +1365,10 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
            ret = -TARGET_EFAULT;
            goto fail;
        }
        if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) {
            ret = -TARGET_EINVAL;
            goto fail;
        }
        addr = alloca(addrlen);
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
    } else {