qemu-devel.nongnu.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).