--- /dev/null
+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;
--- /dev/null
+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;
--- /dev/null
+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. */
--- /dev/null
+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;
+ }