]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 14 Dec 2012 23:30:06 +0000 (15:30 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 14 Dec 2012 23:30:06 +0000 (15:30 -0800)
added patches:
bonding-bonding-driver-does-not-consider-the-gso_max_size-gso_max_segs-setting-of-slave-devices.patch
bonding-fix-race-condition-in-bonding_store_slaves_active.patch
inet_diag-avoid-unsafe-and-nonsensical-prefix-matches-in-inet_diag_bc_run.patch
inet_diag-fix-oops-for-ipv4-af_inet6-tcp-syn-recv-state.patch
inet_diag-validate-byte-code-to-prevent-oops-in-inet_diag_bc_run.patch
inet_diag-validate-port-comparison-byte-code-to-prevent-unsafe-reads.patch
ipv4-avoid-passing-null-to-inet_putpeer-in-icmpv4_xrlim_allow.patch
ipv4-do-not-cache-looped-multicasts.patch
ipv4-ip_check_defrag-must-not-modify-skb-before-unsharing.patch
ipv6-fix-inet6_csk_update_pmtu-return-value.patch
irda-sir_dev-fix-copy-paste-typo.patch
ne2000-add-the-right-platform-device.patch
net-cdc_ncm-add-huawei-devices.patch
sctp-fix-enomem-result-with-invalid-user-space-pointer-in-sendto-syscall.patch
sctp-fix-memory-leak-in-sctp_datamsg_from_user-when-copy-from-user-space-fails.patch
sis900-fix-sis900_set_mode-call-parameters.patch
usb-ipheth-add-iphone-5-support.patch

18 files changed:
queue-3.6/bonding-bonding-driver-does-not-consider-the-gso_max_size-gso_max_segs-setting-of-slave-devices.patch [new file with mode: 0644]
queue-3.6/bonding-fix-race-condition-in-bonding_store_slaves_active.patch [new file with mode: 0644]
queue-3.6/inet_diag-avoid-unsafe-and-nonsensical-prefix-matches-in-inet_diag_bc_run.patch [new file with mode: 0644]
queue-3.6/inet_diag-fix-oops-for-ipv4-af_inet6-tcp-syn-recv-state.patch [new file with mode: 0644]
queue-3.6/inet_diag-validate-byte-code-to-prevent-oops-in-inet_diag_bc_run.patch [new file with mode: 0644]
queue-3.6/inet_diag-validate-port-comparison-byte-code-to-prevent-unsafe-reads.patch [new file with mode: 0644]
queue-3.6/ipv4-avoid-passing-null-to-inet_putpeer-in-icmpv4_xrlim_allow.patch [new file with mode: 0644]
queue-3.6/ipv4-do-not-cache-looped-multicasts.patch [new file with mode: 0644]
queue-3.6/ipv4-ip_check_defrag-must-not-modify-skb-before-unsharing.patch [new file with mode: 0644]
queue-3.6/ipv6-fix-inet6_csk_update_pmtu-return-value.patch [new file with mode: 0644]
queue-3.6/irda-sir_dev-fix-copy-paste-typo.patch [new file with mode: 0644]
queue-3.6/ne2000-add-the-right-platform-device.patch [new file with mode: 0644]
queue-3.6/net-cdc_ncm-add-huawei-devices.patch [new file with mode: 0644]
queue-3.6/sctp-fix-enomem-result-with-invalid-user-space-pointer-in-sendto-syscall.patch [new file with mode: 0644]
queue-3.6/sctp-fix-memory-leak-in-sctp_datamsg_from_user-when-copy-from-user-space-fails.patch [new file with mode: 0644]
queue-3.6/series
queue-3.6/sis900-fix-sis900_set_mode-call-parameters.patch [new file with mode: 0644]
queue-3.6/usb-ipheth-add-iphone-5-support.patch [new file with mode: 0644]

diff --git a/queue-3.6/bonding-bonding-driver-does-not-consider-the-gso_max_size-gso_max_segs-setting-of-slave-devices.patch b/queue-3.6/bonding-bonding-driver-does-not-consider-the-gso_max_size-gso_max_segs-setting-of-slave-devices.patch
new file mode 100644 (file)
index 0000000..6716fb7
--- /dev/null
@@ -0,0 +1,48 @@
+From 131b0a9682568ceb61a62ca7eb49cfe9d2300c1e Mon Sep 17 00:00:00 2001
+From: Sarveshwar Bandi <sarveshwar.bandi@emulex.com>
+Date: Wed, 21 Nov 2012 04:35:03 +0000
+Subject: bonding: Bonding driver does not consider the gso_max_size/gso_max_segs setting of slave devices.
+
+
+From: Sarveshwar Bandi <sarveshwar.bandi@emulex.com>
+
+[ Upstream commit 0e376bd0b791ac6ac6bdb051492df0769c840848 ]
+
+Patch sets the lowest gso_max_size and gso_max_segs values of the slave devices during enslave and detach.
+
+Signed-off-by: Sarveshwar Bandi <sarveshwar.bandi@emulex.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/bonding/bond_main.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1379,6 +1379,8 @@ static void bond_compute_features(struct
+       struct net_device *bond_dev = bond->dev;
+       netdev_features_t vlan_features = BOND_VLAN_FEATURES;
+       unsigned short max_hard_header_len = ETH_HLEN;
++      unsigned int gso_max_size = GSO_MAX_SIZE;
++      u16 gso_max_segs = GSO_MAX_SEGS;
+       int i;
+       unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE;
+@@ -1394,11 +1396,16 @@ static void bond_compute_features(struct
+               dst_release_flag &= slave->dev->priv_flags;
+               if (slave->dev->hard_header_len > max_hard_header_len)
+                       max_hard_header_len = slave->dev->hard_header_len;
++
++              gso_max_size = min(gso_max_size, slave->dev->gso_max_size);
++              gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs);
+       }
+ done:
+       bond_dev->vlan_features = vlan_features;
+       bond_dev->hard_header_len = max_hard_header_len;
++      bond_dev->gso_max_segs = gso_max_segs;
++      netif_set_gso_max_size(bond_dev, gso_max_size);
+       flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE;
+       bond_dev->priv_flags = flags | dst_release_flag;
diff --git a/queue-3.6/bonding-fix-race-condition-in-bonding_store_slaves_active.patch b/queue-3.6/bonding-fix-race-condition-in-bonding_store_slaves_active.patch
new file mode 100644 (file)
index 0000000..972b347
--- /dev/null
@@ -0,0 +1,44 @@
+From aeb5aaacd12d81c3c74491921d45546330cd5f03 Mon Sep 17 00:00:00 2001
+From: "nikolay@redhat.com" <nikolay@redhat.com>
+Date: Thu, 29 Nov 2012 01:37:59 +0000
+Subject: bonding: fix race condition in bonding_store_slaves_active
+
+
+From: "nikolay@redhat.com" <nikolay@redhat.com>
+
+[ Upstream commit e196c0e579902f42cf72414461fb034e5a1ffbf7 ]
+
+Race between bonding_store_slaves_active() and slave manipulation
+ functions. The bond_for_each_slave use in bonding_store_slaves_active()
+ is not protected by any synchronization mechanism.
+ NULL pointer dereference is easy to reach.
+ Fixed by acquiring the bond->lock for the slave walk.
+
+ v2: Make description text < 75 columns
+
+Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
+Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/bonding/bond_sysfs.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/bonding/bond_sysfs.c
++++ b/drivers/net/bonding/bond_sysfs.c
+@@ -1582,6 +1582,7 @@ static ssize_t bonding_store_slaves_acti
+               goto out;
+       }
++      read_lock(&bond->lock);
+       bond_for_each_slave(bond, slave, i) {
+               if (!bond_is_active_slave(slave)) {
+                       if (new_value)
+@@ -1590,6 +1591,7 @@ static ssize_t bonding_store_slaves_acti
+                               slave->inactive = 1;
+               }
+       }
++      read_unlock(&bond->lock);
+ out:
+       return ret;
+ }
diff --git a/queue-3.6/inet_diag-avoid-unsafe-and-nonsensical-prefix-matches-in-inet_diag_bc_run.patch b/queue-3.6/inet_diag-avoid-unsafe-and-nonsensical-prefix-matches-in-inet_diag_bc_run.patch
new file mode 100644 (file)
index 0000000..53a0571
--- /dev/null
@@ -0,0 +1,81 @@
+From 0d86ed6504fae203488056e16309e0f7727143d3 Mon Sep 17 00:00:00 2001
+From: Neal Cardwell <ncardwell@google.com>
+Date: Sat, 8 Dec 2012 19:43:23 +0000
+Subject: inet_diag: avoid unsafe and nonsensical prefix matches in inet_diag_bc_run()
+
+
+From: Neal Cardwell <ncardwell@google.com>
+
+[ Upstream commit f67caec9068cee426ec23cf9005a1dee2ecad187 ]
+
+Add logic to check the address family of the user-supplied conditional
+and the address family of the connection entry. We now do not do
+prefix matching of addresses from different address families (AF_INET
+vs AF_INET6), except for the previously existing support for having an
+IPv4 prefix match an IPv4-mapped IPv6 address (which this commit
+maintains as-is).
+
+This change is needed for two reasons:
+
+(1) The addresses are different lengths, so comparing a 128-bit IPv6
+prefix match condition to a 32-bit IPv4 connection address can cause
+us to unwittingly walk off the end of the IPv4 address and read
+garbage or oops.
+
+(2) The IPv4 and IPv6 address spaces are semantically distinct, so a
+simple bit-wise comparison of the prefixes is not meaningful, and
+would lead to bogus results (except for the IPv4-mapped IPv6 case,
+which this commit maintains).
+
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/inet_diag.c |   28 +++++++++++++++++-----------
+ 1 file changed, 17 insertions(+), 11 deletions(-)
+
+--- a/net/ipv4/inet_diag.c
++++ b/net/ipv4/inet_diag.c
+@@ -427,25 +427,31 @@ static int inet_diag_bc_run(const struct
+                               break;
+                       }
+-                      if (cond->prefix_len == 0)
+-                              break;
+-
+                       if (op->code == INET_DIAG_BC_S_COND)
+                               addr = entry->saddr;
+                       else
+                               addr = entry->daddr;
++                      if (cond->family != AF_UNSPEC &&
++                          cond->family != entry->family) {
++                              if (entry->family == AF_INET6 &&
++                                  cond->family == AF_INET) {
++                                      if (addr[0] == 0 && addr[1] == 0 &&
++                                          addr[2] == htonl(0xffff) &&
++                                          bitstring_match(addr + 3,
++                                                          cond->addr,
++                                                          cond->prefix_len))
++                                              break;
++                              }
++                              yes = 0;
++                              break;
++                      }
++
++                      if (cond->prefix_len == 0)
++                              break;
+                       if (bitstring_match(addr, cond->addr,
+                                           cond->prefix_len))
+                               break;
+-                      if (entry->family == AF_INET6 &&
+-                          cond->family == AF_INET) {
+-                              if (addr[0] == 0 && addr[1] == 0 &&
+-                                  addr[2] == htonl(0xffff) &&
+-                                  bitstring_match(addr + 3, cond->addr,
+-                                                  cond->prefix_len))
+-                                      break;
+-                      }
+                       yes = 0;
+                       break;
+               }
diff --git a/queue-3.6/inet_diag-fix-oops-for-ipv4-af_inet6-tcp-syn-recv-state.patch b/queue-3.6/inet_diag-fix-oops-for-ipv4-af_inet6-tcp-syn-recv-state.patch
new file mode 100644 (file)
index 0000000..65090cc
--- /dev/null
@@ -0,0 +1,113 @@
+From 3d11b89b94c1e53f5f895d6a6b045566711fc8ca Mon Sep 17 00:00:00 2001
+From: Neal Cardwell <ncardwell@google.com>
+Date: Sat, 8 Dec 2012 19:43:21 +0000
+Subject: inet_diag: fix oops for IPv4 AF_INET6 TCP SYN-RECV state
+
+
+From: Neal Cardwell <ncardwell@google.com>
+
+[ Upstream commit 1c95df85ca49640576de2f0a850925957b547b84 ]
+
+Fix inet_diag to be aware of the fact that AF_INET6 TCP connections
+instantiated for IPv4 traffic and in the SYN-RECV state were actually
+created with inet_reqsk_alloc(), instead of inet6_reqsk_alloc(). This
+means that for such connections inet6_rsk(req) returns a pointer to a
+random spot in memory up to roughly 64KB beyond the end of the
+request_sock.
+
+With this bug, for a server using AF_INET6 TCP sockets and serving
+IPv4 traffic, an inet_diag user like `ss state SYN-RECV` would lead to
+inet_diag_fill_req() causing an oops or the export to user space of 16
+bytes of kernel memory as a garbage IPv6 address, depending on where
+the garbage inet6_rsk(req) pointed.
+
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/inet_diag.c |   53 +++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 39 insertions(+), 14 deletions(-)
+
+--- a/net/ipv4/inet_diag.c
++++ b/net/ipv4/inet_diag.c
+@@ -44,6 +44,10 @@ struct inet_diag_entry {
+       u16 dport;
+       u16 family;
+       u16 userlocks;
++#if IS_ENABLED(CONFIG_IPV6)
++      struct in6_addr saddr_storage;  /* for IPv4-mapped-IPv6 addresses */
++      struct in6_addr daddr_storage;  /* for IPv4-mapped-IPv6 addresses */
++#endif
+ };
+ static DEFINE_MUTEX(inet_diag_table_mutex);
+@@ -590,6 +594,36 @@ static int inet_twsk_diag_dump(struct in
+                                  cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
+ }
++/* Get the IPv4, IPv6, or IPv4-mapped-IPv6 local and remote addresses
++ * from a request_sock. For IPv4-mapped-IPv6 we must map IPv4 to IPv6.
++ */
++static inline void inet_diag_req_addrs(const struct sock *sk,
++                                     const struct request_sock *req,
++                                     struct inet_diag_entry *entry)
++{
++      struct inet_request_sock *ireq = inet_rsk(req);
++
++#if IS_ENABLED(CONFIG_IPV6)
++      if (sk->sk_family == AF_INET6) {
++              if (req->rsk_ops->family == AF_INET6) {
++                      entry->saddr = inet6_rsk(req)->loc_addr.s6_addr32;
++                      entry->daddr = inet6_rsk(req)->rmt_addr.s6_addr32;
++              } else if (req->rsk_ops->family == AF_INET) {
++                      ipv6_addr_set_v4mapped(ireq->loc_addr,
++                                             &entry->saddr_storage);
++                      ipv6_addr_set_v4mapped(ireq->rmt_addr,
++                                             &entry->daddr_storage);
++                      entry->saddr = entry->saddr_storage.s6_addr32;
++                      entry->daddr = entry->daddr_storage.s6_addr32;
++              }
++      } else
++#endif
++      {
++              entry->saddr = &ireq->loc_addr;
++              entry->daddr = &ireq->rmt_addr;
++      }
++}
++
+ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
+                             struct request_sock *req, u32 pid, u32 seq,
+                             const struct nlmsghdr *unlh)
+@@ -629,8 +663,10 @@ static int inet_diag_fill_req(struct sk_
+       r->idiag_inode = 0;
+ #if IS_ENABLED(CONFIG_IPV6)
+       if (r->idiag_family == AF_INET6) {
+-              *(struct in6_addr *)r->id.idiag_src = inet6_rsk(req)->loc_addr;
+-              *(struct in6_addr *)r->id.idiag_dst = inet6_rsk(req)->rmt_addr;
++              struct inet_diag_entry entry;
++              inet_diag_req_addrs(sk, req, &entry);
++              memcpy(r->id.idiag_src, entry.saddr, sizeof(struct in6_addr));
++              memcpy(r->id.idiag_dst, entry.daddr, sizeof(struct in6_addr));
+       }
+ #endif
+@@ -683,18 +719,7 @@ static int inet_diag_dump_reqs(struct sk
+                               continue;
+                       if (bc) {
+-                              entry.saddr =
+-#if IS_ENABLED(CONFIG_IPV6)
+-                                      (entry.family == AF_INET6) ?
+-                                      inet6_rsk(req)->loc_addr.s6_addr32 :
+-#endif
+-                                      &ireq->loc_addr;
+-                              entry.daddr =
+-#if IS_ENABLED(CONFIG_IPV6)
+-                                      (entry.family == AF_INET6) ?
+-                                      inet6_rsk(req)->rmt_addr.s6_addr32 :
+-#endif
+-                                      &ireq->rmt_addr;
++                              inet_diag_req_addrs(sk, req, &entry);
+                               entry.dport = ntohs(ireq->rmt_port);
+                               if (!inet_diag_bc_run(bc, &entry))
diff --git a/queue-3.6/inet_diag-validate-byte-code-to-prevent-oops-in-inet_diag_bc_run.patch b/queue-3.6/inet_diag-validate-byte-code-to-prevent-oops-in-inet_diag_bc_run.patch
new file mode 100644 (file)
index 0000000..028d8e0
--- /dev/null
@@ -0,0 +1,110 @@
+From eb1545daf210041bf3bc8ec683a43a11f1361fe6 Mon Sep 17 00:00:00 2001
+From: Neal Cardwell <ncardwell@google.com>
+Date: Sat, 8 Dec 2012 19:43:22 +0000
+Subject: inet_diag: validate byte code to prevent oops in inet_diag_bc_run()
+
+
+From: Neal Cardwell <ncardwell@google.com>
+
+[ Upstream commit 405c005949e47b6e91359159c24753519ded0c67 ]
+
+Add logic to validate INET_DIAG_BC_S_COND and INET_DIAG_BC_D_COND
+operations.
+
+Previously we did not validate the inet_diag_hostcond, address family,
+address length, and prefix length. So a malicious user could make the
+kernel read beyond the end of the bytecode array by claiming to have a
+whole inet_diag_hostcond when the bytecode was not long enough to
+contain a whole inet_diag_hostcond of the given address family. Or
+they could make the kernel read up to about 27 bytes beyond the end of
+a connection address by passing a prefix length that exceeded the
+length of addresses of the given family.
+
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/inet_diag.c |   48 +++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 45 insertions(+), 3 deletions(-)
+
+--- a/net/ipv4/inet_diag.c
++++ b/net/ipv4/inet_diag.c
+@@ -508,6 +508,44 @@ static int valid_cc(const void *bc, int
+       return 0;
+ }
++/* Validate an inet_diag_hostcond. */
++static bool valid_hostcond(const struct inet_diag_bc_op *op, int len,
++                         int *min_len)
++{
++      int addr_len;
++      struct inet_diag_hostcond *cond;
++
++      /* Check hostcond space. */
++      *min_len += sizeof(struct inet_diag_hostcond);
++      if (len < *min_len)
++              return false;
++      cond = (struct inet_diag_hostcond *)(op + 1);
++
++      /* Check address family and address length. */
++      switch (cond->family) {
++      case AF_UNSPEC:
++              addr_len = 0;
++              break;
++      case AF_INET:
++              addr_len = sizeof(struct in_addr);
++              break;
++      case AF_INET6:
++              addr_len = sizeof(struct in6_addr);
++              break;
++      default:
++              return false;
++      }
++      *min_len += addr_len;
++      if (len < *min_len)
++              return false;
++
++      /* Check prefix length (in bits) vs address length (in bytes). */
++      if (cond->prefix_len > 8 * addr_len)
++              return false;
++
++      return true;
++}
++
+ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len)
+ {
+       const void *bc = bytecode;
+@@ -515,18 +553,22 @@ static int inet_diag_bc_audit(const void
+       while (len > 0) {
+               const struct inet_diag_bc_op *op = bc;
++              int min_len = sizeof(struct inet_diag_bc_op);
+ //printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len);
+               switch (op->code) {
+-              case INET_DIAG_BC_AUTO:
+               case INET_DIAG_BC_S_COND:
+               case INET_DIAG_BC_D_COND:
++                      if (!valid_hostcond(bc, len, &min_len))
++                              return -EINVAL;
++                      /* fall through */
++              case INET_DIAG_BC_AUTO:
+               case INET_DIAG_BC_S_GE:
+               case INET_DIAG_BC_S_LE:
+               case INET_DIAG_BC_D_GE:
+               case INET_DIAG_BC_D_LE:
+               case INET_DIAG_BC_JMP:
+-                      if (op->no < 4 || op->no > len + 4 || op->no & 3)
++                      if (op->no < min_len || op->no > len + 4 || op->no & 3)
+                               return -EINVAL;
+                       if (op->no < len &&
+                           !valid_cc(bytecode, bytecode_len, len - op->no))
+@@ -537,7 +579,7 @@ static int inet_diag_bc_audit(const void
+               default:
+                       return -EINVAL;
+               }
+-              if (op->yes < 4 || op->yes > len + 4 || op->yes & 3)
++              if (op->yes < min_len || op->yes > len + 4 || op->yes & 3)
+                       return -EINVAL;
+               bc  += op->yes;
+               len -= op->yes;
diff --git a/queue-3.6/inet_diag-validate-port-comparison-byte-code-to-prevent-unsafe-reads.patch b/queue-3.6/inet_diag-validate-port-comparison-byte-code-to-prevent-unsafe-reads.patch
new file mode 100644 (file)
index 0000000..d28c346
--- /dev/null
@@ -0,0 +1,86 @@
+From cd82550381feeb004a3afddffcf9f911763f051a Mon Sep 17 00:00:00 2001
+From: Neal Cardwell <ncardwell@google.com>
+Date: Sun, 9 Dec 2012 11:09:54 +0000
+Subject: inet_diag: validate port comparison byte code to prevent unsafe reads
+
+
+From: Neal Cardwell <ncardwell@google.com>
+
+[ Upstream commit 5e1f54201cb481f40a04bc47e1bc8c093a189e23 ]
+
+Add logic to verify that a port comparison byte code operation
+actually has the second inet_diag_bc_op from which we read the port
+for such operations.
+
+Previously the code blindly referenced op[1] without first checking
+whether a second inet_diag_bc_op struct could fit there. So a
+malicious user could make the kernel read 4 bytes beyond the end of
+the bytecode array by claiming to have a whole port comparison byte
+code (2 inet_diag_bc_op structs) when in fact the bytecode was not
+long enough to hold both.
+
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/inet_diag.c |   31 ++++++++++++++++++++++++-------
+ 1 file changed, 24 insertions(+), 7 deletions(-)
+
+--- a/net/ipv4/inet_diag.c
++++ b/net/ipv4/inet_diag.c
+@@ -552,6 +552,17 @@ static bool valid_hostcond(const struct
+       return true;
+ }
++/* Validate a port comparison operator. */
++static inline bool valid_port_comparison(const struct inet_diag_bc_op *op,
++                                       int len, int *min_len)
++{
++      /* Port comparisons put the port in a follow-on inet_diag_bc_op. */
++      *min_len += sizeof(struct inet_diag_bc_op);
++      if (len < *min_len)
++              return false;
++      return true;
++}
++
+ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len)
+ {
+       const void *bc = bytecode;
+@@ -567,24 +578,30 @@ static int inet_diag_bc_audit(const void
+               case INET_DIAG_BC_D_COND:
+                       if (!valid_hostcond(bc, len, &min_len))
+                               return -EINVAL;
+-                      /* fall through */
+-              case INET_DIAG_BC_AUTO:
++                      break;
+               case INET_DIAG_BC_S_GE:
+               case INET_DIAG_BC_S_LE:
+               case INET_DIAG_BC_D_GE:
+               case INET_DIAG_BC_D_LE:
+-              case INET_DIAG_BC_JMP:
+-                      if (op->no < min_len || op->no > len + 4 || op->no & 3)
+-                              return -EINVAL;
+-                      if (op->no < len &&
+-                          !valid_cc(bytecode, bytecode_len, len - op->no))
++                      if (!valid_port_comparison(bc, len, &min_len))
+                               return -EINVAL;
+                       break;
++              case INET_DIAG_BC_AUTO:
++              case INET_DIAG_BC_JMP:
+               case INET_DIAG_BC_NOP:
+                       break;
+               default:
+                       return -EINVAL;
+               }
++
++              if (op->code != INET_DIAG_BC_NOP) {
++                      if (op->no < min_len || op->no > len + 4 || op->no & 3)
++                              return -EINVAL;
++                      if (op->no < len &&
++                          !valid_cc(bytecode, bytecode_len, len - op->no))
++                              return -EINVAL;
++              }
++
+               if (op->yes < min_len || op->yes > len + 4 || op->yes & 3)
+                       return -EINVAL;
+               bc  += op->yes;
diff --git a/queue-3.6/ipv4-avoid-passing-null-to-inet_putpeer-in-icmpv4_xrlim_allow.patch b/queue-3.6/ipv4-avoid-passing-null-to-inet_putpeer-in-icmpv4_xrlim_allow.patch
new file mode 100644 (file)
index 0000000..1baea85
--- /dev/null
@@ -0,0 +1,37 @@
+From 788229f19d20bd6644a2ebca359ecd54e4ce1b1a Mon Sep 17 00:00:00 2001
+From: Neal Cardwell <ncardwell@google.com>
+Date: Sat, 24 Nov 2012 18:54:37 +0000
+Subject: ipv4: avoid passing NULL to inet_putpeer() in icmpv4_xrlim_allow()
+
+
+From: Neal Cardwell <ncardwell@google.com>
+
+[ Upstream commit e1a676424c290b1c8d757e3860170ac7ecd89af4 ]
+
+inet_getpeer_v4() can return NULL under OOM conditions, and while
+inet_peer_xrlim_allow() is OK with a NULL peer, inet_putpeer() will
+crash.
+
+This code path now uses the same idiom as the others from:
+1d861aa4b3fb08822055345f480850205ffe6170 ("inet: Minimize use of
+cached route inetpeer.").
+
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/icmp.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -257,7 +257,8 @@ static inline bool icmpv4_xrlim_allow(st
+               struct inet_peer *peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, 1);
+               rc = inet_peer_xrlim_allow(peer,
+                                          net->ipv4.sysctl_icmp_ratelimit);
+-              inet_putpeer(peer);
++              if (peer)
++                      inet_putpeer(peer);
+       }
+ out:
+       return rc;
diff --git a/queue-3.6/ipv4-do-not-cache-looped-multicasts.patch b/queue-3.6/ipv4-do-not-cache-looped-multicasts.patch
new file mode 100644 (file)
index 0000000..3862ca6
--- /dev/null
@@ -0,0 +1,67 @@
+From 38c3bfd5aca185ba44c0b418d9bbb7619d95be01 Mon Sep 17 00:00:00 2001
+From: Julian Anastasov <ja@ssi.bg>
+Date: Thu, 22 Nov 2012 23:04:14 +0200
+Subject: ipv4: do not cache looped multicasts
+
+
+From: Julian Anastasov <ja@ssi.bg>
+
+[ Upstream commit 636174219b52b5a8bc51bc23bbcba97cd30a65e3 ]
+
+       Starting from 3.6 we cache output routes for
+multicasts only when using route to 224/4. For local receivers
+we can set RTCF_LOCAL flag depending on the membership but
+in such case we use maddr and saddr which are not caching
+keys as before. Additionally, we can not use same place to
+cache routes that differ in RTCF_LOCAL flag value.
+
+       Fix it by caching only RTCF_MULTICAST entries
+without RTCF_LOCAL (send-only, no loopback). As a side effect,
+we avoid unneeded lookup for fnhe when not caching because
+multicasts are not redirected and they do not learn PMTU.
+
+       Thanks to Maxime Bizon for showing the caching
+problems in __mkroute_output for 3.6 kernels: different
+RTCF_LOCAL flag in cache can lead to wrong ip_mc_output or
+ip_output call and the visible problem is that traffic can
+not reach local receivers via loopback.
+
+Reported-by: Maxime Bizon <mbizon@freebox.fr>
+Tested-by: Maxime Bizon <mbizon@freebox.fr>
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/route.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -1785,6 +1785,7 @@ static struct rtable *__mkroute_output(c
+       if (dev_out->flags & IFF_LOOPBACK)
+               flags |= RTCF_LOCAL;
++      do_cache = true;
+       if (type == RTN_BROADCAST) {
+               flags |= RTCF_BROADCAST | RTCF_LOCAL;
+               fi = NULL;
+@@ -1793,6 +1794,8 @@ static struct rtable *__mkroute_output(c
+               if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr,
+                                    fl4->flowi4_proto))
+                       flags &= ~RTCF_LOCAL;
++              else
++                      do_cache = false;
+               /* If multicast route do not exist use
+                * default one, but do not gateway in this case.
+                * Yes, it is hack.
+@@ -1802,8 +1805,8 @@ static struct rtable *__mkroute_output(c
+       }
+       fnhe = NULL;
+-      do_cache = fi != NULL;
+-      if (fi) {
++      do_cache &= fi != NULL;
++      if (do_cache) {
+               struct rtable __rcu **prth;
+               struct fib_nh *nh = &FIB_RES_NH(*res);
diff --git a/queue-3.6/ipv4-ip_check_defrag-must-not-modify-skb-before-unsharing.patch b/queue-3.6/ipv4-ip_check_defrag-must-not-modify-skb-before-unsharing.patch
new file mode 100644 (file)
index 0000000..10bd648
--- /dev/null
@@ -0,0 +1,68 @@
+From 11c14577a9b031bc1f97880187083aae6369bcbf Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Sun, 9 Dec 2012 23:41:06 +0000
+Subject: ipv4: ip_check_defrag must not modify skb before unsharing
+
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 1bf3751ec90cc3174e01f0d701e8449ce163d113 ]
+
+ip_check_defrag() might be called from af_packet within the
+RX path where shared SKBs are used, so it must not modify
+the input SKB before it has unshared it for defragmentation.
+Use skb_copy_bits() to get the IP header and only pull in
+everything later.
+
+The same is true for the other caller in macvlan as it is
+called from dev->rx_handler which can also get a shared SKB.
+
+Reported-by: Eric Leblond <eric@regit.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ip_fragment.c |   19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+--- a/net/ipv4/ip_fragment.c
++++ b/net/ipv4/ip_fragment.c
+@@ -702,28 +702,27 @@ EXPORT_SYMBOL(ip_defrag);
+ struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user)
+ {
+-      const struct iphdr *iph;
++      struct iphdr iph;
+       u32 len;
+       if (skb->protocol != htons(ETH_P_IP))
+               return skb;
+-      if (!pskb_may_pull(skb, sizeof(struct iphdr)))
++      if (!skb_copy_bits(skb, 0, &iph, sizeof(iph)))
+               return skb;
+-      iph = ip_hdr(skb);
+-      if (iph->ihl < 5 || iph->version != 4)
++      if (iph.ihl < 5 || iph.version != 4)
+               return skb;
+-      if (!pskb_may_pull(skb, iph->ihl*4))
+-              return skb;
+-      iph = ip_hdr(skb);
+-      len = ntohs(iph->tot_len);
+-      if (skb->len < len || len < (iph->ihl * 4))
++
++      len = ntohs(iph.tot_len);
++      if (skb->len < len || len < (iph.ihl * 4))
+               return skb;
+-      if (ip_is_fragment(ip_hdr(skb))) {
++      if (ip_is_fragment(&iph)) {
+               skb = skb_share_check(skb, GFP_ATOMIC);
+               if (skb) {
++                      if (!pskb_may_pull(skb, iph.ihl*4))
++                              return skb;
+                       if (pskb_trim_rcsum(skb, len))
+                               return skb;
+                       memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
diff --git a/queue-3.6/ipv6-fix-inet6_csk_update_pmtu-return-value.patch b/queue-3.6/ipv6-fix-inet6_csk_update_pmtu-return-value.patch
new file mode 100644 (file)
index 0000000..313bf52
--- /dev/null
@@ -0,0 +1,35 @@
+From c11042076efb15940639c20af9bf318c02bc6843 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 20 Nov 2012 15:14:51 -0500
+Subject: ipv6: fix inet6_csk_update_pmtu() return value
+
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b4dd006760d671337b62532277b0296bcee8dfd4 ]
+
+In case of error, inet6_csk_update_pmtu() should consistently
+return NULL.
+
+Bug added in commit 35ad9b9cf7d8a
+(ipv6: Add helper inet6_csk_update_pmtu().)
+
+Reported-by: Lluís Batlle i Rossell <viric@viric.name>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/inet6_connection_sock.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/ipv6/inet6_connection_sock.c
++++ b/net/ipv6/inet6_connection_sock.c
+@@ -252,6 +252,7 @@ struct dst_entry *inet6_csk_update_pmtu(
+               return NULL;
+       dst->ops->update_pmtu(dst, sk, NULL, mtu);
+-      return inet6_csk_route_socket(sk, &fl6);
++      dst = inet6_csk_route_socket(sk, &fl6);
++      return IS_ERR(dst) ? NULL : dst;
+ }
+ EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu);
diff --git a/queue-3.6/irda-sir_dev-fix-copy-paste-typo.patch b/queue-3.6/irda-sir_dev-fix-copy-paste-typo.patch
new file mode 100644 (file)
index 0000000..561f45d
--- /dev/null
@@ -0,0 +1,28 @@
+From f9e1b66306c3fbfc99118595f2b4513c64a2a766 Mon Sep 17 00:00:00 2001
+From: Alexander Shiyan <shc_work@mail.ru>
+Date: Tue, 20 Nov 2012 09:59:11 +0000
+Subject: irda: sir_dev: Fix copy/paste typo
+
+
+From: Alexander Shiyan <shc_work@mail.ru>
+
+[ Upstream commit 2355a62bcbdcc4b567425bab036bfab6ade87eed ]
+
+Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/irda/sir_dev.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/irda/sir_dev.c
++++ b/drivers/net/irda/sir_dev.c
+@@ -222,7 +222,7 @@ static void sirdev_config_fsm(struct wor
+                       break;
+               case SIRDEV_STATE_DONGLE_SPEED:
+-                      if (dev->dongle_drv->reset) {
++                      if (dev->dongle_drv->set_speed) {
+                               ret = dev->dongle_drv->set_speed(dev, fsm->param);
+                               if (ret < 0) {
+                                       fsm->result = ret;
diff --git a/queue-3.6/ne2000-add-the-right-platform-device.patch b/queue-3.6/ne2000-add-the-right-platform-device.patch
new file mode 100644 (file)
index 0000000..5c27608
--- /dev/null
@@ -0,0 +1,30 @@
+From 7e515aacab26d3a84874ba523023b8d23d36d3ec Mon Sep 17 00:00:00 2001
+From: Alan Cox <alan@linux.intel.com>
+Date: Tue, 20 Nov 2012 06:31:57 +0000
+Subject: ne2000: add the right platform device
+
+
+From: Alan Cox <alan@linux.intel.com>
+
+[ Upstream commit da9da01d9199b5bb15289d0859053c9aa3a34ac0 ]
+
+Without this udev doesn't have a way to key the ne device to the platform
+device.
+
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/8390/ne.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ethernet/8390/ne.c
++++ b/drivers/net/ethernet/8390/ne.c
+@@ -813,6 +813,7 @@ static int __init ne_drv_probe(struct pl
+               dev->irq = irq[this_dev];
+               dev->mem_end = bad[this_dev];
+       }
++      SET_NETDEV_DEV(dev, &pdev->dev);
+       err = do_ne_probe(dev);
+       if (err) {
+               free_netdev(dev);
diff --git a/queue-3.6/net-cdc_ncm-add-huawei-devices.patch b/queue-3.6/net-cdc_ncm-add-huawei-devices.patch
new file mode 100644 (file)
index 0000000..6f45481
--- /dev/null
@@ -0,0 +1,82 @@
+From 62d865cfeca0b6c6e4d9f10f4755b3883c1e4575 Mon Sep 17 00:00:00 2001
+From: Bjørn Mork <bjorn@mork.no>
+Date: Tue, 13 Nov 2012 03:19:43 +0000
+Subject: net: cdc_ncm: add Huawei devices
+
+
+From: Bjørn Mork <bjorn@mork.no>
+
+[ Upstream commit bbc8d9228ea8e37ce29fa96150d10b85a2c7be60 ]
+
+A number of Huawei 3G and LTE modems implement a CDC NCM function,
+including the necessary functional descriptors, but using a non
+standard interface layout and class/subclass/protocol codes.
+
+These devices can be handled by this driver with only a minor
+change to the probing logic, allowing a single combined control
+and data interface.  This works because the devices
+- include a CDC Union descriptor labelling the combined
+  interface as both master and slave, and
+- have an alternate setting #1 for the bulk endpoints on the
+  combined interface.
+
+The 3G/LTE network connection is managed by vendor specific AT
+commands on a serial function in the same composite device.
+Handling the managment function is out of the scope of this
+driver.  It will be handled by an appropriate USB serial
+driver.
+
+Reported-and-Tested-by: Olof Ermis <olof.ermis@gmail.com>
+Reported-and-Tested-by: Tommy Cheng <tommy7765@yahoo.com>
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/cdc_ncm.c |   22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/usb/cdc_ncm.c
++++ b/drivers/net/usb/cdc_ncm.c
+@@ -540,10 +540,12 @@ advance:
+           (ctx->ether_desc == NULL) || (ctx->control != intf))
+               goto error;
+-      /* claim interfaces, if any */
+-      temp = usb_driver_claim_interface(driver, ctx->data, dev);
+-      if (temp)
+-              goto error;
++      /* claim data interface, if different from control */
++      if (ctx->data != ctx->control) {
++              temp = usb_driver_claim_interface(driver, ctx->data, dev);
++              if (temp)
++                      goto error;
++      }
+       iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
+@@ -623,6 +625,10 @@ static void cdc_ncm_unbind(struct usbnet
+       tasklet_kill(&ctx->bh);
++      /* handle devices with combined control and data interface */
++      if (ctx->control == ctx->data)
++              ctx->data = NULL;
++
+       /* disconnect master --> disconnect slave */
+       if (intf == ctx->control && ctx->data) {
+               usb_set_intfdata(ctx->data, NULL);
+@@ -1245,6 +1251,14 @@ static const struct usb_device_id cdc_de
+         .driver_info = (unsigned long) &wwan_info,
+       },
++      /* Huawei NCM devices disguised as vendor specific */
++      { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16),
++        .driver_info = (unsigned long)&wwan_info,
++      },
++      { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46),
++        .driver_info = (unsigned long)&wwan_info,
++      },
++
+       /* Generic CDC-NCM devices */
+       { USB_INTERFACE_INFO(USB_CLASS_COMM,
+               USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
diff --git a/queue-3.6/sctp-fix-enomem-result-with-invalid-user-space-pointer-in-sendto-syscall.patch b/queue-3.6/sctp-fix-enomem-result-with-invalid-user-space-pointer-in-sendto-syscall.patch
new file mode 100644 (file)
index 0000000..bdc9f59
--- /dev/null
@@ -0,0 +1,117 @@
+From cf64e7ab7564ea8dfc7a51e46261950ae2460abb Mon Sep 17 00:00:00 2001
+From: Tommi Rantala <tt.rantala@gmail.com>
+Date: Thu, 22 Nov 2012 03:23:16 +0000
+Subject: sctp: fix -ENOMEM result with invalid user space pointer in sendto() syscall
+
+
+From: Tommi Rantala <tt.rantala@gmail.com>
+
+[ Upstream commit 6e51fe7572590d8d86e93b547fab6693d305fd0d ]
+
+Consider the following program, that sets the second argument to the
+sendto() syscall incorrectly:
+
+ #include <string.h>
+ #include <arpa/inet.h>
+ #include <sys/socket.h>
+
+ int main(void)
+ {
+         int fd;
+         struct sockaddr_in sa;
+
+         fd = socket(AF_INET, SOCK_STREAM, 132 /*IPPROTO_SCTP*/);
+         if (fd < 0)
+                 return 1;
+
+         memset(&sa, 0, sizeof(sa));
+         sa.sin_family = AF_INET;
+         sa.sin_addr.s_addr = inet_addr("127.0.0.1");
+         sa.sin_port = htons(11111);
+
+         sendto(fd, NULL, 1, 0, (struct sockaddr *)&sa, sizeof(sa));
+
+         return 0;
+ }
+
+We get -ENOMEM:
+
+ $ strace -e sendto ./demo
+ sendto(3, NULL, 1, 0, {sa_family=AF_INET, sin_port=htons(11111), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 ENOMEM (Cannot allocate memory)
+
+Propagate the error code from sctp_user_addto_chunk(), so that we will
+tell user space what actually went wrong:
+
+ $ strace -e sendto ./demo
+ sendto(3, NULL, 1, 0, {sa_family=AF_INET, sin_port=htons(11111), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EFAULT (Bad address)
+
+Noticed while running Trinity (the syscall fuzzer).
+
+Signed-off-by: Tommi Rantala <tt.rantala@gmail.com>
+Acked-by: Vlad Yasevich <vyasevich@gmail.com>
+Acked-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/chunk.c  |   13 +++++++++----
+ net/sctp/socket.c |    4 ++--
+ 2 files changed, 11 insertions(+), 6 deletions(-)
+
+--- a/net/sctp/chunk.c
++++ b/net/sctp/chunk.c
+@@ -183,7 +183,7 @@ struct sctp_datamsg *sctp_datamsg_from_u
+       msg = sctp_datamsg_new(GFP_KERNEL);
+       if (!msg)
+-              return NULL;
++              return ERR_PTR(-ENOMEM);
+       /* Note: Calculate this outside of the loop, so that all fragments
+        * have the same expiration.
+@@ -280,8 +280,11 @@ struct sctp_datamsg *sctp_datamsg_from_u
+               chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0);
+-              if (!chunk)
++              if (!chunk) {
++                      err = -ENOMEM;
+                       goto errout;
++              }
++
+               err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov);
+               if (err < 0)
+                       goto errout_chunk_free;
+@@ -315,8 +318,10 @@ struct sctp_datamsg *sctp_datamsg_from_u
+               chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0);
+-              if (!chunk)
++              if (!chunk) {
++                      err = -ENOMEM;
+                       goto errout;
++              }
+               err = sctp_user_addto_chunk(chunk, offset, over,msgh->msg_iov);
+@@ -342,7 +347,7 @@ errout:
+               sctp_chunk_free(chunk);
+       }
+       sctp_datamsg_put(msg);
+-      return NULL;
++      return ERR_PTR(err);
+ }
+ /* Check whether this message has expired. */
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -1908,8 +1908,8 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
+       /* Break the message into multiple chunks of maximum size. */
+       datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len);
+-      if (!datamsg) {
+-              err = -ENOMEM;
++      if (IS_ERR(datamsg)) {
++              err = PTR_ERR(datamsg);
+               goto out_free;
+       }
diff --git a/queue-3.6/sctp-fix-memory-leak-in-sctp_datamsg_from_user-when-copy-from-user-space-fails.patch b/queue-3.6/sctp-fix-memory-leak-in-sctp_datamsg_from_user-when-copy-from-user-space-fails.patch
new file mode 100644 (file)
index 0000000..0bba44f
--- /dev/null
@@ -0,0 +1,77 @@
+From 189e72643f2fd31b1a47f2c6f8ba6f25b74e10c0 Mon Sep 17 00:00:00 2001
+From: Tommi Rantala <tt.rantala@gmail.com>
+Date: Tue, 27 Nov 2012 04:01:46 +0000
+Subject: sctp: fix memory leak in sctp_datamsg_from_user() when copy from user space fails
+
+
+From: Tommi Rantala <tt.rantala@gmail.com>
+
+[ Upstream commit be364c8c0f17a3dd42707b5a090b318028538eb9 ]
+
+Trinity (the syscall fuzzer) discovered a memory leak in SCTP,
+reproducible e.g. with the sendto() syscall by passing invalid
+user space pointer in the second argument:
+
+ #include <string.h>
+ #include <arpa/inet.h>
+ #include <sys/socket.h>
+
+ int main(void)
+ {
+         int fd;
+         struct sockaddr_in sa;
+
+         fd = socket(AF_INET, SOCK_STREAM, 132 /*IPPROTO_SCTP*/);
+         if (fd < 0)
+                 return 1;
+
+         memset(&sa, 0, sizeof(sa));
+         sa.sin_family = AF_INET;
+         sa.sin_addr.s_addr = inet_addr("127.0.0.1");
+         sa.sin_port = htons(11111);
+
+         sendto(fd, NULL, 1, 0, (struct sockaddr *)&sa, sizeof(sa));
+
+         return 0;
+ }
+
+As far as I can tell, the leak has been around since ~2003.
+
+Signed-off-by: Tommi Rantala <tt.rantala@gmail.com>
+Acked-by: Vlad Yasevich <vyasevich@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/chunk.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/net/sctp/chunk.c
++++ b/net/sctp/chunk.c
+@@ -284,7 +284,7 @@ struct sctp_datamsg *sctp_datamsg_from_u
+                       goto errout;
+               err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov);
+               if (err < 0)
+-                      goto errout;
++                      goto errout_chunk_free;
+               offset += len;
+@@ -324,7 +324,7 @@ struct sctp_datamsg *sctp_datamsg_from_u
+               __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr
+                          - (__u8 *)chunk->skb->data);
+               if (err < 0)
+-                      goto errout;
++                      goto errout_chunk_free;
+               sctp_datamsg_assign(msg, chunk);
+               list_add_tail(&chunk->frag_list, &msg->chunks);
+@@ -332,6 +332,9 @@ struct sctp_datamsg *sctp_datamsg_from_u
+       return msg;
++errout_chunk_free:
++      sctp_chunk_free(chunk);
++
+ errout:
+       list_for_each_safe(pos, temp, &msg->chunks) {
+               list_del_init(pos);
index 0bb561750c634cad7bfd987e48c6c4c284e8fcb0..e15b01538801f79120790b1ea26bb200184f8319 100644 (file)
@@ -35,3 +35,20 @@ perf-test-fix-a-build-error-on-builtin-test.patch
 usb-ehci-bugfix-urb-hcpriv-should-not-be-null.patch
 rcu-fix-batch-limit-size-problem.patch
 pci-pm-fix-deadlock-when-unbinding-device-if-parent-in-d3cold.patch
+sis900-fix-sis900_set_mode-call-parameters.patch
+ne2000-add-the-right-platform-device.patch
+ipv6-fix-inet6_csk_update_pmtu-return-value.patch
+irda-sir_dev-fix-copy-paste-typo.patch
+ipv4-do-not-cache-looped-multicasts.patch
+ipv4-avoid-passing-null-to-inet_putpeer-in-icmpv4_xrlim_allow.patch
+ipv4-ip_check_defrag-must-not-modify-skb-before-unsharing.patch
+inet_diag-fix-oops-for-ipv4-af_inet6-tcp-syn-recv-state.patch
+inet_diag-validate-byte-code-to-prevent-oops-in-inet_diag_bc_run.patch
+inet_diag-avoid-unsafe-and-nonsensical-prefix-matches-in-inet_diag_bc_run.patch
+inet_diag-validate-port-comparison-byte-code-to-prevent-unsafe-reads.patch
+usb-ipheth-add-iphone-5-support.patch
+net-cdc_ncm-add-huawei-devices.patch
+bonding-bonding-driver-does-not-consider-the-gso_max_size-gso_max_segs-setting-of-slave-devices.patch
+bonding-fix-race-condition-in-bonding_store_slaves_active.patch
+sctp-fix-memory-leak-in-sctp_datamsg_from_user-when-copy-from-user-space-fails.patch
+sctp-fix-enomem-result-with-invalid-user-space-pointer-in-sendto-syscall.patch
diff --git a/queue-3.6/sis900-fix-sis900_set_mode-call-parameters.patch b/queue-3.6/sis900-fix-sis900_set_mode-call-parameters.patch
new file mode 100644 (file)
index 0000000..bf30b15
--- /dev/null
@@ -0,0 +1,35 @@
+From 7a90119352331eeb36ee60415b3c55311e4a92a8 Mon Sep 17 00:00:00 2001
+From: Francois Romieu <romieu@fr.zoreil.com>
+Date: Sun, 18 Nov 2012 23:41:50 +0100
+Subject: sis900: fix sis900_set_mode call parameters.
+
+
+From: Francois Romieu <romieu@fr.zoreil.com>
+
+[ Upstream commit 8495c0da20bc496ac9d5da2b292adb28f61d2713 ]
+
+Leftover of 57d6d456cfb89264f87d24f52640ede23fdf12bd ("sis900: stop
+using net_device.{base_addr, irq} and convert to __iomem.").
+
+It is needed for suspend / resume to work.
+
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Tested-by: Jan Janssen <medhefgo@web.de>
+Cc: Daniele Venzano <venza@brownhat.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/sis/sis900.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/sis/sis900.c
++++ b/drivers/net/ethernet/sis/sis900.c
+@@ -2477,7 +2477,7 @@ static int sis900_resume(struct pci_dev
+       netif_start_queue(net_dev);
+       /* Workaround for EDB */
+-      sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
++      sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
+       /* Enable all known interrupts by setting the interrupt mask. */
+       sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
diff --git a/queue-3.6/usb-ipheth-add-iphone-5-support.patch b/queue-3.6/usb-ipheth-add-iphone-5-support.patch
new file mode 100644 (file)
index 0000000..a7d8685
--- /dev/null
@@ -0,0 +1,44 @@
+From 9f22a3c3dc6059f8fe8850272a3df014e80f77d4 Mon Sep 17 00:00:00 2001
+From: Jay Purohit <jspurohit@velocitylimitless.com>
+Date: Sun, 14 Oct 2012 07:07:21 +0000
+Subject: usb/ipheth: Add iPhone 5 support
+
+
+From: Jay Purohit <jspurohit@velocitylimitless.com>
+
+[ Upstream commit af1b85e49089f945deb46258b0fc4bc9910afb22 ]
+
+I noticed that the iPhone ethernet driver did not support
+iPhone 5. I quickly added support to it in my kernel, here's
+a patch.
+
+Signed-off-by: Jay Purohit <jspurohit@velocitylimitless.com>
+Acked-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>
+Signed-off-by: Jan Ceuleers <jan.ceuleers@computer.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/ipheth.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/usb/ipheth.c
++++ b/drivers/net/usb/ipheth.c
+@@ -62,6 +62,7 @@
+ #define USB_PRODUCT_IPAD 0x129a
+ #define USB_PRODUCT_IPHONE_4_VZW 0x129c
+ #define USB_PRODUCT_IPHONE_4S 0x12a0
++#define USB_PRODUCT_IPHONE_5  0x12a8
+ #define IPHETH_USBINTF_CLASS    255
+ #define IPHETH_USBINTF_SUBCLASS 253
+@@ -113,6 +114,10 @@ static struct usb_device_id ipheth_table
+               USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S,
+               IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+               IPHETH_USBINTF_PROTO) },
++      { USB_DEVICE_AND_INTERFACE_INFO(
++              USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_5,
++              IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
++              IPHETH_USBINTF_PROTO) },
+       { }
+ };
+ MODULE_DEVICE_TABLE(usb, ipheth_table);