All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] linux-user/syscall: check some parameters for some socket syscalls.
Date: Thu, 18 Jun 2009 13:43:38 +0200	[thread overview]
Message-ID: <87ocslsr6d.fsf@lechat.rtp-net.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 527 bytes --]


This patch is fixing following issues :

- commit 8fea36025b9d6d360ff3b78f88a84ccf221807e8 was applied to
  do_getsockname instead of do_accept.
- Some syscalls were not checking properly the memory addresses passed
  as argument
- Add check before syscalls made for cases like do_getpeername() where
  we're using the address parameter after doing the syscall
- Fix do_accept to return EINVAL instead of EFAULT when parameters
  invalid to match with linux behaviour

Signed-off-by: Arnaud Patard <arnaud.patard@rtp-net.org>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: net_syscall_parameters_check.patch --]
[-- Type: text/x-diff, Size: 3505 bytes --]

Index: qemu/linux-user/syscall.c
===================================================================
--- qemu.orig/linux-user/syscall.c
+++ qemu/linux-user/syscall.c
@@ -1499,13 +1499,17 @@ static abi_long do_bind(int sockfd, abi_
                         socklen_t addrlen)
 {
     void *addr;
+    abi_long ret;
 
     if (addrlen < 0)
         return -TARGET_EINVAL;
 
     addr = alloca(addrlen+1);
 
-    target_to_host_sockaddr(addr, target_addr, addrlen);
+    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
+    if (ret)
+	    return ret;
+
     return get_errno(bind(sockfd, addr, addrlen));
 }
 
@@ -1514,13 +1518,17 @@ static abi_long do_connect(int sockfd, a
                            socklen_t addrlen)
 {
     void *addr;
+    abi_long ret;
 
     if (addrlen < 0)
         return -TARGET_EINVAL;
 
     addr = alloca(addrlen);
 
-    target_to_host_sockaddr(addr, target_addr, addrlen);
+    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
+    if (ret)
+	    return ret;
+
     return get_errno(connect(sockfd, addr, addrlen));
 }
 
@@ -1544,8 +1552,12 @@ static abi_long do_sendrecvmsg(int fd, a
     if (msgp->msg_name) {
         msg.msg_namelen = tswap32(msgp->msg_namelen);
         msg.msg_name = alloca(msg.msg_namelen);
-        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
+        ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
                                 msg.msg_namelen);
+	if (ret) {
+		unlock_user_struct(msgp, target_msg, send ? 0 : 1);
+		return ret;
+	}
     } else {
         msg.msg_name = NULL;
         msg.msg_namelen = 0;
@@ -1587,12 +1599,19 @@ static abi_long do_accept(int fd, abi_ul
     void *addr;
     abi_long ret;
 
+    if (target_addr == 0)
+       return get_errno(accept(fd, NULL, NULL));
+
+    /* linux returns EINVAL if addrlen pointer is invalid */
     if (get_user_u32(addrlen, target_addrlen_addr))
-        return -TARGET_EFAULT;
+        return -TARGET_EINVAL;
 
     if (addrlen < 0)
         return -TARGET_EINVAL;
 
+    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
+	    return -TARGET_EINVAL;
+
     addr = alloca(addrlen);
 
     ret = get_errno(accept(fd, addr, &addrlen));
@@ -1618,6 +1637,9 @@ static abi_long do_getpeername(int fd, a
     if (addrlen < 0)
         return -TARGET_EINVAL;
 
+    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
+	    return -TARGET_EFAULT;
+
     addr = alloca(addrlen);
 
     ret = get_errno(getpeername(fd, addr, &addrlen));
@@ -1637,15 +1659,15 @@ static abi_long do_getsockname(int fd, a
     void *addr;
     abi_long ret;
 
-    if (target_addr == 0)
-       return get_errno(accept(fd, NULL, NULL));
-
     if (get_user_u32(addrlen, target_addrlen_addr))
         return -TARGET_EFAULT;
 
     if (addrlen < 0)
         return -TARGET_EINVAL;
 
+    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
+	    return -TARGET_EFAULT;
+
     addr = alloca(addrlen);
 
     ret = get_errno(getsockname(fd, addr, &addrlen));
@@ -1689,7 +1711,11 @@ static abi_long do_sendto(int fd, abi_ul
         return -TARGET_EFAULT;
     if (target_addr) {
         addr = alloca(addrlen);
-        target_to_host_sockaddr(addr, target_addr, addrlen);
+        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
+	if (ret) {
+		unlock_user(host_msg, msg, 0);
+		return ret;
+	}
         ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
     } else {
         ret = get_errno(send(fd, host_msg, len, flags));

                 reply	other threads:[~2009-06-18 11:38 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87ocslsr6d.fsf@lechat.rtp-net.org \
    --to=arnaud.patard@rtp-net.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.