]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.33 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 7 Dec 2010 21:34:38 +0000 (13:34 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 7 Dec 2010 21:34:38 +0000 (13:34 -0800)
queue-2.6.33/econet-disallow-null-remote-addr-for-sendmsg-fixes-cve-2010-3849.patch [new file with mode: 0644]
queue-2.6.33/econet-fix-cve-2010-3848.patch [new file with mode: 0644]
queue-2.6.33/econet-fix-cve-2010-3850.patch [new file with mode: 0644]
queue-2.6.33/rds-integer-overflow-in-rds-cmsg-handling.patch [new file with mode: 0644]
queue-2.6.33/series

diff --git a/queue-2.6.33/econet-disallow-null-remote-addr-for-sendmsg-fixes-cve-2010-3849.patch b/queue-2.6.33/econet-disallow-null-remote-addr-for-sendmsg-fixes-cve-2010-3849.patch
new file mode 100644 (file)
index 0000000..f10edc1
--- /dev/null
@@ -0,0 +1,62 @@
+From fa0e846494792e722d817b9d3d625a4ef4896c96 Mon Sep 17 00:00:00 2001
+From: Phil Blundell <philb@gnu.org>
+Date: Wed, 24 Nov 2010 11:49:19 -0800
+Subject: econet: disallow NULL remote addr for sendmsg(), fixes CVE-2010-3849
+
+From: Phil Blundell <philb@gnu.org>
+
+commit fa0e846494792e722d817b9d3d625a4ef4896c96 upstream.
+
+Later parts of econet_sendmsg() rely on saddr != NULL, so return early
+with EINVAL if NULL was passed otherwise an oops may occur.
+
+Signed-off-by: Phil Blundell <philb@gnu.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/econet/af_econet.c |   26 ++++++++------------------
+ 1 file changed, 8 insertions(+), 18 deletions(-)
+
+--- a/net/econet/af_econet.c
++++ b/net/econet/af_econet.c
+@@ -296,23 +296,14 @@ static int econet_sendmsg(struct kiocb *
+       mutex_lock(&econet_mutex);
+-      if (saddr == NULL) {
+-              struct econet_sock *eo = ec_sk(sk);
+-
+-              addr.station = eo->station;
+-              addr.net     = eo->net;
+-              port         = eo->port;
+-              cb           = eo->cb;
+-      } else {
+-              if (msg->msg_namelen < sizeof(struct sockaddr_ec)) {
+-                      mutex_unlock(&econet_mutex);
+-                      return -EINVAL;
+-              }
+-              addr.station = saddr->addr.station;
+-              addr.net = saddr->addr.net;
+-              port = saddr->port;
+-              cb = saddr->cb;
+-      }
++        if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) {
++                mutex_unlock(&econet_mutex);
++                return -EINVAL;
++        }
++        addr.station = saddr->addr.station;
++        addr.net = saddr->addr.net;
++        port = saddr->port;
++        cb = saddr->cb;
+       /* Look for a device with the right network number. */
+       dev = net2dev_map[addr.net];
+@@ -350,7 +341,6 @@ static int econet_sendmsg(struct kiocb *
+               eb = (struct ec_cb *)&skb->cb;
+-              /* BUG: saddr may be NULL */
+               eb->cookie = saddr->cookie;
+               eb->sec = *saddr;
+               eb->sent = ec_tx_done;
diff --git a/queue-2.6.33/econet-fix-cve-2010-3848.patch b/queue-2.6.33/econet-fix-cve-2010-3848.patch
new file mode 100644 (file)
index 0000000..7e55682
--- /dev/null
@@ -0,0 +1,154 @@
+From a27e13d370415add3487949c60810e36069a23a6 Mon Sep 17 00:00:00 2001
+From: Phil Blundell <philb@gnu.org>
+Date: Wed, 24 Nov 2010 11:51:47 -0800
+Subject: econet: fix CVE-2010-3848
+
+From: Phil Blundell <philb@gnu.org>
+
+commit a27e13d370415add3487949c60810e36069a23a6 upstream.
+
+Don't declare variable sized array of iovecs on the stack since this
+could cause stack overflow if msg->msgiovlen is large.  Instead, coalesce
+the user-supplied data into a new buffer and use a single iovec for it.
+
+Signed-off-by: Phil Blundell <philb@gnu.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/econet/af_econet.c |   62 ++++++++++++++++++++++++-------------------------
+ 1 file changed, 31 insertions(+), 31 deletions(-)
+
+--- a/net/econet/af_econet.c
++++ b/net/econet/af_econet.c
+@@ -30,6 +30,7 @@
+ #include <linux/wireless.h>
+ #include <linux/skbuff.h>
+ #include <linux/udp.h>
++#include <linux/vmalloc.h>
+ #include <net/sock.h>
+ #include <net/inet_common.h>
+ #include <linux/stat.h>
+@@ -275,12 +276,12 @@ static int econet_sendmsg(struct kiocb *
+ #endif
+ #ifdef CONFIG_ECONET_AUNUDP
+       struct msghdr udpmsg;
+-      struct iovec iov[msg->msg_iovlen+1];
++      struct iovec iov[2];
+       struct aunhdr ah;
+       struct sockaddr_in udpdest;
+       __kernel_size_t size;
+-      int i;
+       mm_segment_t oldfs;
++      char *userbuf;
+ #endif
+       /*
+@@ -318,17 +319,17 @@ static int econet_sendmsg(struct kiocb *
+               }
+       }
+-      if (len + 15 > dev->mtu) {
+-              mutex_unlock(&econet_mutex);
+-              return -EMSGSIZE;
+-      }
+-
+       if (dev->type == ARPHRD_ECONET) {
+               /* Real hardware Econet.  We're not worthy etc. */
+ #ifdef CONFIG_ECONET_NATIVE
+               unsigned short proto = 0;
+               int res;
++              if (len + 15 > dev->mtu) {
++                      mutex_unlock(&econet_mutex);
++                      return -EMSGSIZE;
++              }
++
+               dev_hold(dev);
+               skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev),
+@@ -404,6 +405,11 @@ static int econet_sendmsg(struct kiocb *
+               return -ENETDOWN;               /* No socket - can't send */
+       }
++      if (len > 32768) {
++              err = -E2BIG;
++              goto error;
++      }
++
+       /* Make up a UDP datagram and hand it off to some higher intellect. */
+       memset(&udpdest, 0, sizeof(udpdest));
+@@ -435,36 +441,26 @@ static int econet_sendmsg(struct kiocb *
+       /* tack our header on the front of the iovec */
+       size = sizeof(struct aunhdr);
+-      /*
+-       * XXX: that is b0rken.  We can't mix userland and kernel pointers
+-       * in iovec, since on a lot of platforms copy_from_user() will
+-       * *not* work with the kernel and userland ones at the same time,
+-       * regardless of what we do with set_fs().  And we are talking about
+-       * econet-over-ethernet here, so "it's only ARM anyway" doesn't
+-       * apply.  Any suggestions on fixing that code?         -- AV
+-       */
+       iov[0].iov_base = (void *)&ah;
+       iov[0].iov_len = size;
+-      for (i = 0; i < msg->msg_iovlen; i++) {
+-              void __user *base = msg->msg_iov[i].iov_base;
+-              size_t iov_len = msg->msg_iov[i].iov_len;
+-              /* Check it now since we switch to KERNEL_DS later. */
+-              if (!access_ok(VERIFY_READ, base, iov_len)) {
+-                      mutex_unlock(&econet_mutex);
+-                      return -EFAULT;
+-              }
+-              iov[i+1].iov_base = base;
+-              iov[i+1].iov_len = iov_len;
+-              size += iov_len;
++
++      userbuf = vmalloc(len);
++      if (userbuf == NULL) {
++              err = -ENOMEM;
++              goto error;
+       }
++      iov[1].iov_base = userbuf;
++      iov[1].iov_len = len;
++      err = memcpy_fromiovec(userbuf, msg->msg_iov, len);
++      if (err)
++              goto error_free_buf;
++
+       /* Get a skbuff (no data, just holds our cb information) */
+       if ((skb = sock_alloc_send_skb(sk, 0,
+                                      msg->msg_flags & MSG_DONTWAIT,
+-                                     &err)) == NULL) {
+-              mutex_unlock(&econet_mutex);
+-              return err;
+-      }
++                                     &err)) == NULL)
++              goto error_free_buf;
+       eb = (struct ec_cb *)&skb->cb;
+@@ -480,7 +476,7 @@ static int econet_sendmsg(struct kiocb *
+       udpmsg.msg_name = (void *)&udpdest;
+       udpmsg.msg_namelen = sizeof(udpdest);
+       udpmsg.msg_iov = &iov[0];
+-      udpmsg.msg_iovlen = msg->msg_iovlen + 1;
++      udpmsg.msg_iovlen = 2;
+       udpmsg.msg_control = NULL;
+       udpmsg.msg_controllen = 0;
+       udpmsg.msg_flags=0;
+@@ -488,9 +484,13 @@ static int econet_sendmsg(struct kiocb *
+       oldfs = get_fs(); set_fs(KERNEL_DS);    /* More privs :-) */
+       err = sock_sendmsg(udpsock, &udpmsg, size);
+       set_fs(oldfs);
++
++error_free_buf:
++      vfree(userbuf);
+ #else
+       err = -EPROTOTYPE;
+ #endif
++      error:
+       mutex_unlock(&econet_mutex);
+       return err;
diff --git a/queue-2.6.33/econet-fix-cve-2010-3850.patch b/queue-2.6.33/econet-fix-cve-2010-3850.patch
new file mode 100644 (file)
index 0000000..24da257
--- /dev/null
@@ -0,0 +1,31 @@
+From 16c41745c7b92a243d0874f534c1655196c64b74 Mon Sep 17 00:00:00 2001
+From: Phil Blundell <philb@gnu.org>
+Date: Wed, 24 Nov 2010 11:49:53 -0800
+Subject: econet: fix CVE-2010-3850
+
+From: Phil Blundell <philb@gnu.org>
+
+commit 16c41745c7b92a243d0874f534c1655196c64b74 upstream.
+
+Add missing check for capable(CAP_NET_ADMIN) in SIOCSIFADDR operation.
+
+Signed-off-by: Phil Blundell <philb@gnu.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/econet/af_econet.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/econet/af_econet.c
++++ b/net/econet/af_econet.c
+@@ -660,6 +660,9 @@ static int ec_dev_ioctl(struct socket *s
+       err = 0;
+       switch (cmd) {
+       case SIOCSIFADDR:
++              if (!capable(CAP_NET_ADMIN))
++                      return -EPERM;
++
+               edev = dev->ec_ptr;
+               if (edev == NULL) {
+                       /* Magic up a new one. */
diff --git a/queue-2.6.33/rds-integer-overflow-in-rds-cmsg-handling.patch b/queue-2.6.33/rds-integer-overflow-in-rds-cmsg-handling.patch
new file mode 100644 (file)
index 0000000..6e679e5
--- /dev/null
@@ -0,0 +1,36 @@
+From 218854af84038d828a32f061858b1902ed2beec6 Mon Sep 17 00:00:00 2001
+From: Dan Rosenberg <drosenberg@vsecurity.com>
+Date: Wed, 17 Nov 2010 06:37:16 +0000
+Subject: rds: Integer overflow in RDS cmsg handling
+
+From: Dan Rosenberg <drosenberg@vsecurity.com>
+
+commit 218854af84038d828a32f061858b1902ed2beec6 upstream.
+
+In rds_cmsg_rdma_args(), the user-provided args->nr_local value is
+restricted to less than UINT_MAX.  This seems to need a tighter upper
+bound, since the calculation of total iov_size can overflow, resulting
+in a small sock_kmalloc() allocation.  This would probably just result
+in walking off the heap and crashing when calling rds_rdma_pages() with
+a high count value.  If it somehow doesn't crash here, then memory
+corruption could occur soon after.
+
+Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/rds/rdma.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/rds/rdma.c
++++ b/net/rds/rdma.c
+@@ -471,7 +471,7 @@ static struct rds_rdma_op *rds_rdma_prep
+               goto out;
+       }
+-      if (args->nr_local > (u64)UINT_MAX) {
++      if (args->nr_local > UIO_MAXIOV) {
+               ret = -EMSGSIZE;
+               goto out;
+       }
index 86130d900393da5ca81c62362b4572a7e62e34bc..b82e63841ad154d87637f0055d28efec64c9687a 100644 (file)
@@ -203,3 +203,7 @@ can-bcm-fix-minor-heap-overflow.patch
 v4l-dvb-ivtvfb-prevent-reading-uninitialized-stack-memory.patch
 x25-prevent-crashing-when-parsing-bad-x.25-facilities.patch
 crypto-padlock-fix-aes-cbc-handling-on-odd-block-sized-input.patch
+econet-disallow-null-remote-addr-for-sendmsg-fixes-cve-2010-3849.patch
+econet-fix-cve-2010-3850.patch
+econet-fix-cve-2010-3848.patch
+rds-integer-overflow-in-rds-cmsg-handling.patch