]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
networking patches for .26
authorGreg Kroah-Hartman <gregkh@suse.de>
Mon, 6 Oct 2008 21:34:44 +0000 (14:34 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 6 Oct 2008 21:34:44 +0000 (14:34 -0700)
queue-2.6.26/0001-af_key-Free-dumping-state-on-socket-close.patch [new file with mode: 0644]
queue-2.6.26/0002-XFRM-IPv6-initialize-ip6_dst_blackhole_ops.kmem_cac.patch [new file with mode: 0644]
queue-2.6.26/0003-ipv6-Fix-OOPS-in-ip6_dst_lookup_tail.patch [new file with mode: 0644]
queue-2.6.26/0004-niu-panic-on-reset.patch [new file with mode: 0644]
queue-2.6.26/0005-netlink-fix-overrun-in-attribute-iteration.patch [new file with mode: 0644]
queue-2.6.26/0006-ipsec-Fix-pskb_expand_head-corruption-in-xfrm_state.patch [new file with mode: 0644]
queue-2.6.26/0007-sctp-do-not-enable-peer-features-if-we-can-t-do-the.patch [new file with mode: 0644]
queue-2.6.26/0008-sctp-Fix-oops-when-INIT-ACK-indicates-that-peer-doe.patch [new file with mode: 0644]
queue-2.6.26/0009-udp-Fix-rcv-socket-locking.patch [new file with mode: 0644]
queue-2.6.26/series

diff --git a/queue-2.6.26/0001-af_key-Free-dumping-state-on-socket-close.patch b/queue-2.6.26/0001-af_key-Free-dumping-state-on-socket-close.patch
new file mode 100644 (file)
index 0000000..8e96950
--- /dev/null
@@ -0,0 +1,71 @@
+From 47b2e18f3ac4a76a8fbb4f71f756381e054f9a5d Mon Sep 17 00:00:00 2001
+From: Timo Teras <timo.teras@iki.fi>
+Date: Wed, 1 Oct 2008 05:17:54 -0700
+Subject: af_key: Free dumping state on socket close
+Message-Id: <20081006.121755.252192371.davem@davemloft.net>
+
+From: Timo Teras <timo.teras@iki.fi>
+
+[ Upstream commit 0523820482dcb42784572ffd2296c2f08c275a2b ]
+
+Fix a xfrm_{state,policy}_walk leak if pfkey socket is closed while
+dumping is on-going.
+
+Signed-off-by: Timo Teras <timo.teras@iki.fi>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+
+---
+ net/key/af_key.c |   30 +++++++++++++++++++-----------
+ 1 file changed, 19 insertions(+), 11 deletions(-)
+
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -73,22 +73,18 @@ static int pfkey_can_dump(struct sock *s
+       return 0;
+ }
+-static int pfkey_do_dump(struct pfkey_sock *pfk)
++static void pfkey_terminate_dump(struct pfkey_sock *pfk)
+ {
+-      int rc;
+-
+-      rc = pfk->dump.dump(pfk);
+-      if (rc == -ENOBUFS)
+-              return 0;
+-
+-      pfk->dump.done(pfk);
+-      pfk->dump.dump = NULL;
+-      pfk->dump.done = NULL;
+-      return rc;
++      if (pfk->dump.dump) {
++              pfk->dump.done(pfk);
++              pfk->dump.dump = NULL;
++              pfk->dump.done = NULL;
++      }
+ }
+ static void pfkey_sock_destruct(struct sock *sk)
+ {
++      pfkey_terminate_dump(pfkey_sk(sk));
+       skb_queue_purge(&sk->sk_receive_queue);
+       if (!sock_flag(sk, SOCK_DEAD)) {
+@@ -310,6 +306,18 @@ static int pfkey_broadcast(struct sk_buf
+       return err;
+ }
++static int pfkey_do_dump(struct pfkey_sock *pfk)
++{
++      int rc;
++
++      rc = pfk->dump.dump(pfk);
++      if (rc == -ENOBUFS)
++              return 0;
++
++      pfkey_terminate_dump(pfk);
++      return rc;
++}
++
+ static inline void pfkey_hdr_dup(struct sadb_msg *new, struct sadb_msg *orig)
+ {
+       *new = *orig;
diff --git a/queue-2.6.26/0002-XFRM-IPv6-initialize-ip6_dst_blackhole_ops.kmem_cac.patch b/queue-2.6.26/0002-XFRM-IPv6-initialize-ip6_dst_blackhole_ops.kmem_cac.patch
new file mode 100644 (file)
index 0000000..143141e
--- /dev/null
@@ -0,0 +1,72 @@
+From e4ed7cb2596af3a066d6a6db0495d22d729350ba Mon Sep 17 00:00:00 2001
+From: Arnaud Ebalard <arno@natisbad.org>
+Date: Wed, 1 Oct 2008 02:37:56 -0700
+Subject: XFRM,IPv6: initialize ip6_dst_blackhole_ops.kmem_cachep
+Message-Id: <20081006.121755.252192371.davem@davemloft.net>
+
+From: Arnaud Ebalard <arno@natisbad.org>
+
+[ Upstream commit 5dc121e9a7a8a3721cefeb07f3559f50fbedc67e ]
+
+ip6_dst_blackhole_ops.kmem_cachep is not expected to be NULL (i.e. to
+be initialized) when dst_alloc() is called from ip6_dst_blackhole().
+Otherwise, it results in the following (xfrm_larval_drop is now set to
+1 by default):
+
+[   78.697642] Unable to handle kernel paging request for data at address 0x0000004c
+[   78.703449] Faulting instruction address: 0xc0097f54
+[   78.786896] Oops: Kernel access of bad area, sig: 11 [#1]
+[   78.792791] PowerMac
+[   78.798383] Modules linked in: btusb usbhid bluetooth b43 mac80211 cfg80211 ehci_hcd ohci_hcd sungem sungem_phy usbcore ssb
+[   78.804263] NIP: c0097f54 LR: c0334a28 CTR: c002d430
+[   78.809997] REGS: eef19ad0 TRAP: 0300   Not tainted  (2.6.27-rc5)
+[   78.815743] MSR: 00001032 <ME,IR,DR>  CR: 22242482  XER: 20000000
+[   78.821550] DAR: 0000004c, DSISR: 40000000
+[   78.827278] TASK = eef0df40[3035] 'mip6d' THREAD: eef18000
+[   78.827408] GPR00: 00001032 eef19b80 eef0df40 00000000 00008020 eef19c30 00000001 00000000
+[   78.833249] GPR08: eee5101c c05a5c10 ef9ad500 00000000 24242422 1005787c 00000000 1004f960
+[   78.839151] GPR16: 00000000 10024e90 10050040 48030018 0fe44150 00000000 00000000 eef19c30
+[   78.845046] GPR24: eef19e44 00000000 eef19bf8 efb37c14 eef19bf8 00008020 00009032 c0596064
+[   78.856671] NIP [c0097f54] kmem_cache_alloc+0x20/0x94
+[   78.862581] LR [c0334a28] dst_alloc+0x40/0xc4
+[   78.868451] Call Trace:
+[   78.874252] [eef19b80] [c03c1810] ip6_dst_lookup_tail+0x1c8/0x1dc (unreliable)
+[   78.880222] [eef19ba0] [c0334a28] dst_alloc+0x40/0xc4
+[   78.886164] [eef19bb0] [c03cd698] ip6_dst_blackhole+0x28/0x1cc
+[   78.892090] [eef19be0] [c03d9be8] rawv6_sendmsg+0x75c/0xc88
+[   78.897999] [eef19cb0] [c038bca4] inet_sendmsg+0x4c/0x78
+[   78.903907] [eef19cd0] [c03207c8] sock_sendmsg+0xac/0xe4
+[   78.909734] [eef19db0] [c03209e4] sys_sendmsg+0x1e4/0x2a0
+[   78.915540] [eef19f00] [c03220a8] sys_socketcall+0xfc/0x210
+[   78.921406] [eef19f40] [c0014b3c] ret_from_syscall+0x0/0x38
+[   78.927295] --- Exception: c01 at 0xfe2d730
+[   78.927297]     LR = 0xfe2d71c
+[   78.939019] Instruction dump:
+[   78.944835] 91640018 9144001c 900a0000 4bffff44 9421ffe0 7c0802a6 bf810010 7c9d2378
+[   78.950694] 90010024 7fc000a6 57c0045e 7c000124 <83e3004c> 8383005c 2f9f0000 419e0050
+[   78.956464] ---[ end trace 05fa1ed7972487a1 ]---
+
+As commented by Benjamin Thery, the bug was introduced by
+f2fc6a54585a1be6669613a31fbaba2ecbadcd36, while adding network
+namespaces support to ipv6 routes.
+
+Signed-off-by: Arnaud Ebalard <arno@natisbad.org>
+Acked-by: Benjamin Thery <benjamin.thery@bull.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv6/route.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -2718,6 +2718,8 @@ int __init ip6_route_init(void)
+       if (ret)
+               goto out_kmem_cache;
++      ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep;
++
+       /* Registering of the loopback is done before this portion of code,
+        * the loopback reference in rt6_info will not be taken, do it
+        * manually for init_net */
diff --git a/queue-2.6.26/0003-ipv6-Fix-OOPS-in-ip6_dst_lookup_tail.patch b/queue-2.6.26/0003-ipv6-Fix-OOPS-in-ip6_dst_lookup_tail.patch
new file mode 100644 (file)
index 0000000..1b34c5b
--- /dev/null
@@ -0,0 +1,105 @@
+From 71d2aefb510cc14d2500f10f02903be4e967a22c Mon Sep 17 00:00:00 2001
+From: Neil Horman <nhorman@tuxdriver.com>
+Date: Tue, 9 Sep 2008 13:51:35 -0700
+Subject: ipv6: Fix OOPS in ip6_dst_lookup_tail().
+Message-Id: <20081006.121755.252192371.davem@davemloft.net>
+
+From: Neil Horman <nhorman@tuxdriver.com>
+
+[ Upstream commit e550dfb0c2c31b6363aa463a035fc9f8dcaa3c9b ]
+
+This fixes kernel bugzilla 11469: "TUN with 1024 neighbours:
+ip6_dst_lookup_tail NULL crash"
+
+dst->neighbour is not necessarily hooked up at this point
+in the processing path, so blindly dereferencing it is
+the wrong thing to do.  This NULL check exists in other
+similar paths and this case was just an oversight.
+
+Also fix the completely wrong and confusing indentation
+here while we're at it.
+
+Based upon a patch by Evgeniy Polyakov.
+
+Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv6/ip6_output.c |   64 +++++++++++++++++++++++++-------------------------
+ 1 file changed, 32 insertions(+), 32 deletions(-)
+
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -934,39 +934,39 @@ static int ip6_dst_lookup_tail(struct so
+       }
+ #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
+-              /*
+-               * Here if the dst entry we've looked up
+-               * has a neighbour entry that is in the INCOMPLETE
+-               * state and the src address from the flow is
+-               * marked as OPTIMISTIC, we release the found
+-               * dst entry and replace it instead with the
+-               * dst entry of the nexthop router
+-               */
+-              if (!((*dst)->neighbour->nud_state & NUD_VALID)) {
+-                      struct inet6_ifaddr *ifp;
+-                      struct flowi fl_gw;
+-                      int redirect;
+-
+-                      ifp = ipv6_get_ifaddr(net, &fl->fl6_src,
+-                                            (*dst)->dev, 1);
+-
+-                      redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
+-                      if (ifp)
+-                              in6_ifa_put(ifp);
+-
+-                      if (redirect) {
+-                              /*
+-                               * We need to get the dst entry for the
+-                               * default router instead
+-                               */
+-                              dst_release(*dst);
+-                              memcpy(&fl_gw, fl, sizeof(struct flowi));
+-                              memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
+-                              *dst = ip6_route_output(net, sk, &fl_gw);
+-                              if ((err = (*dst)->error))
+-                                      goto out_err_release;
+-                      }
++      /*
++       * Here if the dst entry we've looked up
++       * has a neighbour entry that is in the INCOMPLETE
++       * state and the src address from the flow is
++       * marked as OPTIMISTIC, we release the found
++       * dst entry and replace it instead with the
++       * dst entry of the nexthop router
++       */
++      if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) {
++              struct inet6_ifaddr *ifp;
++              struct flowi fl_gw;
++              int redirect;
++
++              ifp = ipv6_get_ifaddr(net, &fl->fl6_src,
++                                    (*dst)->dev, 1);
++
++              redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
++              if (ifp)
++                      in6_ifa_put(ifp);
++
++              if (redirect) {
++                      /*
++                       * We need to get the dst entry for the
++                       * default router instead
++                       */
++                      dst_release(*dst);
++                      memcpy(&fl_gw, fl, sizeof(struct flowi));
++                      memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
++                      *dst = ip6_route_output(net, sk, &fl_gw);
++                      if ((err = (*dst)->error))
++                              goto out_err_release;
+               }
++      }
+ #endif
+       return 0;
diff --git a/queue-2.6.26/0004-niu-panic-on-reset.patch b/queue-2.6.26/0004-niu-panic-on-reset.patch
new file mode 100644 (file)
index 0000000..8f4ff90
--- /dev/null
@@ -0,0 +1,94 @@
+From bc2a8d36fbc6474e1d890cd759f016c9b8768942 Mon Sep 17 00:00:00 2001
+From: Santwona Behera <santwona.behera@sun.com>
+Date: Fri, 12 Sep 2008 16:04:26 -0700
+Subject: niu: panic on reset
+Message-Id: <20081006.121755.252192371.davem@davemloft.net>
+
+From: Santwona Behera <santwona.behera@sun.com>
+
+[ Upstream commit cff502a38394fd33693f6233e03fca363dfa956d ]
+
+The reset_task function in the niu driver does not reset the tx and rx
+buffers properly. This leads to panic on reset. This patch is a
+modified implementation of the previously posted fix.
+
+Signed-off-by: Santwona Behera <santwona.behera@sun.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/niu.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+--- a/drivers/net/niu.c
++++ b/drivers/net/niu.c
+@@ -5978,6 +5978,56 @@ static void niu_netif_start(struct niu *
+       niu_enable_interrupts(np, 1);
+ }
++static void niu_reset_buffers(struct niu *np)
++{
++      int i, j, k, err;
++
++      if (np->rx_rings) {
++              for (i = 0; i < np->num_rx_rings; i++) {
++                      struct rx_ring_info *rp = &np->rx_rings[i];
++
++                      for (j = 0, k = 0; j < MAX_RBR_RING_SIZE; j++) {
++                              struct page *page;
++
++                              page = rp->rxhash[j];
++                              while (page) {
++                                      struct page *next =
++                                              (struct page *) page->mapping;
++                                      u64 base = page->index;
++                                      base = base >> RBR_DESCR_ADDR_SHIFT;
++                                      rp->rbr[k++] = cpu_to_le32(base);
++                                      page = next;
++                              }
++                      }
++                      for (; k < MAX_RBR_RING_SIZE; k++) {
++                              err = niu_rbr_add_page(np, rp, GFP_ATOMIC, k);
++                              if (unlikely(err))
++                                      break;
++                      }
++
++                      rp->rbr_index = rp->rbr_table_size - 1;
++                      rp->rcr_index = 0;
++                      rp->rbr_pending = 0;
++                      rp->rbr_refill_pending = 0;
++              }
++      }
++      if (np->tx_rings) {
++              for (i = 0; i < np->num_tx_rings; i++) {
++                      struct tx_ring_info *rp = &np->tx_rings[i];
++
++                      for (j = 0; j < MAX_TX_RING_SIZE; j++) {
++                              if (rp->tx_buffs[j].skb)
++                                      (void) release_tx_packet(np, rp, j);
++                      }
++
++                      rp->pending = MAX_TX_RING_SIZE;
++                      rp->prod = 0;
++                      rp->cons = 0;
++                      rp->wrap_bit = 0;
++              }
++      }
++}
++
+ static void niu_reset_task(struct work_struct *work)
+ {
+       struct niu *np = container_of(work, struct niu, reset_task);
+@@ -6000,6 +6050,12 @@ static void niu_reset_task(struct work_s
+       niu_stop_hw(np);
++      spin_unlock_irqrestore(&np->lock, flags);
++
++      niu_reset_buffers(np);
++
++      spin_lock_irqsave(&np->lock, flags);
++
+       err = niu_init_hw(np);
+       if (!err) {
+               np->timer.expires = jiffies + HZ;
diff --git a/queue-2.6.26/0005-netlink-fix-overrun-in-attribute-iteration.patch b/queue-2.6.26/0005-netlink-fix-overrun-in-attribute-iteration.patch
new file mode 100644 (file)
index 0000000..050f029
--- /dev/null
@@ -0,0 +1,93 @@
+From 0df880294bb21639540feae10505e48735ab01df Mon Sep 17 00:00:00 2001
+From: Vegard Nossum <vegard.nossum@gmail.com>
+Date: Thu, 11 Sep 2008 19:05:29 -0700
+Subject: netlink: fix overrun in attribute iteration
+Message-Id: <20081006.121755.252192371.davem@davemloft.net>
+
+From: Vegard Nossum <vegard.nossum@gmail.com>
+
+[ Upstream commit 1045b03e07d85f3545118510a587035536030c1c ]
+
+kmemcheck reported this:
+
+  kmemcheck: Caught 16-bit read from uninitialized memory (f6c1ba30)
+  0500110001508abf050010000500000002017300140000006f72672e66726565
+   i i i i i i i i i i i i i u u u u u u u u u u u u u u u u u u u
+                                   ^
+
+  Pid: 3462, comm: wpa_supplicant Not tainted (2.6.27-rc3-00054-g6397ab9-dirty #13)
+  EIP: 0060:[<c05de64a>] EFLAGS: 00010296 CPU: 0
+  EIP is at nla_parse+0x5a/0xf0
+  EAX: 00000008 EBX: fffffffd ECX: c06f16c0 EDX: 00000005
+  ESI: 00000010 EDI: f6c1ba30 EBP: f6367c6c ESP: c0a11e88
+   DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
+  CR0: 8005003b CR2: f781cc84 CR3: 3632f000 CR4: 000006d0
+  DR0: c0ead9bc DR1: 00000000 DR2: 00000000 DR3: 00000000
+  DR6: ffff4ff0 DR7: 00000400
+   [<c05d4b23>] rtnl_setlink+0x63/0x130
+   [<c05d5f75>] rtnetlink_rcv_msg+0x165/0x200
+   [<c05ddf66>] netlink_rcv_skb+0x76/0xa0
+   [<c05d5dfe>] rtnetlink_rcv+0x1e/0x30
+   [<c05dda21>] netlink_unicast+0x281/0x290
+   [<c05ddbe9>] netlink_sendmsg+0x1b9/0x2b0
+   [<c05beef2>] sock_sendmsg+0xd2/0x100
+   [<c05bf945>] sys_sendto+0xa5/0xd0
+   [<c05bf9a6>] sys_send+0x36/0x40
+   [<c05c03d6>] sys_socketcall+0x1e6/0x2c0
+   [<c020353b>] sysenter_do_call+0x12/0x3f
+   [<ffffffff>] 0xffffffff
+
+This is the line in nla_ok():
+
+  /**
+   * nla_ok - check if the netlink attribute fits into the remaining bytes
+   * @nla: netlink attribute
+   * @remaining: number of bytes remaining in attribute stream
+   */
+  static inline int nla_ok(const struct nlattr *nla, int remaining)
+  {
+          return remaining >= sizeof(*nla) &&
+                 nla->nla_len >= sizeof(*nla) &&
+                 nla->nla_len <= remaining;
+  }
+
+It turns out that remaining can become negative due to alignment in
+nla_next(). But GCC promotes "remaining" to unsigned in the test
+against sizeof(*nla) above. Therefore the test succeeds, and the
+nla_for_each_attr() may access memory outside the received buffer.
+
+A short example illustrating this point is here:
+
+  #include <stdio.h>
+
+  main(void)
+  {
+          printf("%d\n", -1 >= sizeof(int));
+  }
+
+...which prints "1".
+
+This patch adds a cast in front of the sizeof so that GCC will make
+a signed comparison and fix the illegal memory dereference. With the
+patch applied, there is no kmemcheck report.
+
+Signed-off-by: Vegard Nossum <vegard.nossum@gmail.com>
+Acked-by: Thomas Graf <tgraf@suug.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/net/netlink.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/net/netlink.h
++++ b/include/net/netlink.h
+@@ -702,7 +702,7 @@ static inline int nla_len(const struct n
+  */
+ static inline int nla_ok(const struct nlattr *nla, int remaining)
+ {
+-      return remaining >= sizeof(*nla) &&
++      return remaining >= (int) sizeof(*nla) &&
+              nla->nla_len >= sizeof(*nla) &&
+              nla->nla_len <= remaining;
+ }
diff --git a/queue-2.6.26/0006-ipsec-Fix-pskb_expand_head-corruption-in-xfrm_state.patch b/queue-2.6.26/0006-ipsec-Fix-pskb_expand_head-corruption-in-xfrm_state.patch
new file mode 100644 (file)
index 0000000..6961f8d
--- /dev/null
@@ -0,0 +1,41 @@
+From aa70fdd1a256259398a37266755e82fe98b74ca9 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Tue, 30 Sep 2008 02:03:19 -0700
+Subject: ipsec: Fix pskb_expand_head corruption in xfrm_state_check_space
+Message-Id: <20081006.121755.252192371.davem@davemloft.net>
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit d01dbeb6af7a0848063033f73c3d146fec7451f3 ]
+
+We're never supposed to shrink the headroom or tailroom.  In fact,
+shrinking the headroom is a fatal action.
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/xfrm/xfrm_output.c |   10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/net/xfrm/xfrm_output.c
++++ b/net/xfrm/xfrm_output.c
+@@ -27,10 +27,14 @@ static int xfrm_state_check_space(struct
+               - skb_headroom(skb);
+       int ntail = dst->dev->needed_tailroom - skb_tailroom(skb);
+-      if (nhead > 0 || ntail > 0)
+-              return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC);
++      if (nhead <= 0) {
++              if (ntail <= 0)
++                      return 0;
++              nhead = 0;
++      } else if (ntail < 0)
++              ntail = 0;
+-      return 0;
++      return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC);
+ }
+ static int xfrm_output_one(struct sk_buff *skb, int err)
diff --git a/queue-2.6.26/0007-sctp-do-not-enable-peer-features-if-we-can-t-do-the.patch b/queue-2.6.26/0007-sctp-do-not-enable-peer-features-if-we-can-t-do-the.patch
new file mode 100644 (file)
index 0000000..01777f6
--- /dev/null
@@ -0,0 +1,53 @@
+From 88a494c31b96a1fcc4c396493ed551752b2eecba Mon Sep 17 00:00:00 2001
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+Date: Thu, 18 Sep 2008 16:27:38 -0700
+Subject: sctp: do not enable peer features if we can't do them.
+Message-Id: <20081006.121755.252192371.davem@davemloft.net>
+
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+
+[ Upstream commit 0ef46e285c062cbe35d60c0adbff96f530d31c86 ]
+
+Do not enable peer features like addip and auth, if they
+are administratively disabled localy.  If the peer resports
+that he supports something that we don't, neither end can
+use it so enabling it is pointless.  This solves a problem
+when talking to a peer that has auth and addip enabled while
+we do not.  Found by Andrei Pelinescu-Onciul <andrei@iptel.org>.
+
+Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/sctp/sm_make_chunk.c |    9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/net/sctp/sm_make_chunk.c
++++ b/net/sctp/sm_make_chunk.c
+@@ -1886,11 +1886,13 @@ static void sctp_process_ext_param(struc
+                           /* if the peer reports AUTH, assume that he
+                            * supports AUTH.
+                            */
+-                          asoc->peer.auth_capable = 1;
++                          if (sctp_auth_enable)
++                                  asoc->peer.auth_capable = 1;
+                           break;
+                   case SCTP_CID_ASCONF:
+                   case SCTP_CID_ASCONF_ACK:
+-                          asoc->peer.asconf_capable = 1;
++                          if (sctp_addip_enable)
++                                  asoc->peer.asconf_capable = 1;
+                           break;
+                   default:
+                           break;
+@@ -2455,6 +2457,9 @@ static int sctp_process_param(struct sct
+               break;
+       case SCTP_PARAM_SET_PRIMARY:
++              if (!sctp_addip_enable)
++                      goto fall_through;
++
+               addr_param = param.v + sizeof(sctp_addip_param_t);
+               af = sctp_get_af_specific(param_type2af(param.p->type));
diff --git a/queue-2.6.26/0008-sctp-Fix-oops-when-INIT-ACK-indicates-that-peer-doe.patch b/queue-2.6.26/0008-sctp-Fix-oops-when-INIT-ACK-indicates-that-peer-doe.patch
new file mode 100644 (file)
index 0000000..1147132
--- /dev/null
@@ -0,0 +1,70 @@
+From a04944e7ba96894e53e1d4b6d8e947276c3e8de0 Mon Sep 17 00:00:00 2001
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+Date: Thu, 18 Sep 2008 16:28:27 -0700
+Subject: sctp: Fix oops when INIT-ACK indicates that peer doesn't support AUTH
+Message-Id: <20081006.121755.252192371.davem@davemloft.net>
+
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+
+[ Upstream commit add52379dde2e5300e2d574b172e62c6cf43b3d3 ]
+
+If INIT-ACK is received with SupportedExtensions parameter which
+indicates that the peer does not support AUTH, the packet will be
+silently ignore, and sctp_process_init() do cleanup all of the
+transports in the association.
+When T1-Init timer is expires, OOPS happen while we try to choose
+a different init transport.
+
+The solution is to only clean up the non-active transports, i.e
+the ones that the peer added.  However, that introduces a problem
+with sctp_connectx(), because we don't mark the proper state for
+the transports provided by the user.  So, we'll simply mark
+user-provided transports as ACTIVE.  That will allow INIT
+retransmissions to work properly in the sctp_connectx() context
+and prevent the crash.
+
+Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/sctp/associola.c     |    9 +++++----
+ net/sctp/sm_make_chunk.c |    6 ++----
+ 2 files changed, 7 insertions(+), 8 deletions(-)
+
+--- a/net/sctp/associola.c
++++ b/net/sctp/associola.c
+@@ -597,11 +597,12 @@ struct sctp_transport *sctp_assoc_add_pe
+       /* Check to see if this is a duplicate. */
+       peer = sctp_assoc_lookup_paddr(asoc, addr);
+       if (peer) {
++              /* An UNKNOWN state is only set on transports added by
++               * user in sctp_connectx() call.  Such transports should be
++               * considered CONFIRMED per RFC 4960, Section 5.4.
++               */
+               if (peer->state == SCTP_UNKNOWN) {
+-                      if (peer_state == SCTP_ACTIVE)
+-                              peer->state = SCTP_ACTIVE;
+-                      if (peer_state == SCTP_UNCONFIRMED)
+-                              peer->state = SCTP_UNCONFIRMED;
++                      peer->state = SCTP_ACTIVE;
+               }
+               return peer;
+       }
+--- a/net/sctp/sm_make_chunk.c
++++ b/net/sctp/sm_make_chunk.c
+@@ -2321,12 +2321,10 @@ clean_up:
+       /* Release the transport structures. */
+       list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
+               transport = list_entry(pos, struct sctp_transport, transports);
+-              list_del_init(pos);
+-              sctp_transport_free(transport);
++              if (transport->state != SCTP_ACTIVE)
++                      sctp_assoc_rm_peer(asoc, transport);
+       }
+-      asoc->peer.transport_count = 0;
+-
+ nomem:
+       return 0;
+ }
diff --git a/queue-2.6.26/0009-udp-Fix-rcv-socket-locking.patch b/queue-2.6.26/0009-udp-Fix-rcv-socket-locking.patch
new file mode 100644 (file)
index 0000000..cd6daa8
--- /dev/null
@@ -0,0 +1,131 @@
+From 76e439d53465bb2dc6a221ad87eee4d716f8d3a6 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Mon, 15 Sep 2008 11:48:46 -0700
+Subject: udp: Fix rcv socket locking
+Message-Id: <20081006.121755.252192371.davem@davemloft.net>
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 93821778def10ec1e69aa3ac10adee975dad4ff3 ]
+
+The previous patch in response to the recursive locking on IPsec
+reception is broken as it tries to drop the BH socket lock while in
+user context.
+
+This patch fixes it by shrinking the section protected by the
+socket lock to sock_queue_rcv_skb only.  The only reason we added
+the lock is for the accounting which happens in that function.
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/udp.c |   59 +++++++++++++++++++++++++++++++--------------------------
+ 1 file changed, 33 insertions(+), 26 deletions(-)
+
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -950,6 +950,27 @@ int udp_disconnect(struct sock *sk, int 
+       return 0;
+ }
++static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
++{
++      int is_udplite = IS_UDPLITE(sk);
++      int rc;
++
++      if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) {
++              /* Note that an ENOMEM error is charged twice */
++              if (rc == -ENOMEM)
++                      UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS,
++                                       is_udplite);
++              goto drop;
++      }
++
++      return 0;
++
++drop:
++      UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
++      kfree_skb(skb);
++      return -1;
++}
++
+ /* returns:
+  *  -1: error
+  *   0: success
+@@ -988,9 +1009,7 @@ int udp_queue_rcv_skb(struct sock * sk, 
+                   up->encap_rcv != NULL) {
+                       int ret;
+-                      bh_unlock_sock(sk);
+                       ret = (*up->encap_rcv)(sk, skb);
+-                      bh_lock_sock(sk);
+                       if (ret <= 0) {
+                               UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS,
+                                                is_udplite);
+@@ -1042,14 +1061,16 @@ int udp_queue_rcv_skb(struct sock * sk, 
+                       goto drop;
+       }
+-      if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) {
+-              /* Note that an ENOMEM error is charged twice */
+-              if (rc == -ENOMEM)
+-                      UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, is_udplite);
+-              goto drop;
+-      }
++      rc = 0;
+-      return 0;
++      bh_lock_sock(sk);
++      if (!sock_owned_by_user(sk))
++              rc = __udp_queue_rcv_skb(sk, skb);
++      else
++              sk_add_backlog(sk, skb);
++      bh_unlock_sock(sk);
++
++      return rc;
+ drop:
+       UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
+@@ -1087,15 +1108,7 @@ static int __udp4_lib_mcast_deliver(stru
+                               skb1 = skb_clone(skb, GFP_ATOMIC);
+                       if (skb1) {
+-                              int ret = 0;
+-
+-                              bh_lock_sock(sk);
+-                              if (!sock_owned_by_user(sk))
+-                                      ret = udp_queue_rcv_skb(sk, skb1);
+-                              else
+-                                      sk_add_backlog(sk, skb1);
+-                              bh_unlock_sock(sk);
+-
++                              int ret = udp_queue_rcv_skb(sk, skb1);
+                               if (ret > 0)
+                                       /* we should probably re-process instead
+                                        * of dropping packets here. */
+@@ -1188,13 +1201,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, 
+                       uh->dest, inet_iif(skb), udptable);
+       if (sk != NULL) {
+-              int ret = 0;
+-              bh_lock_sock(sk);
+-              if (!sock_owned_by_user(sk))
+-                      ret = udp_queue_rcv_skb(sk, skb);
+-              else
+-                      sk_add_backlog(sk, skb);
+-              bh_unlock_sock(sk);
++              int ret = udp_queue_rcv_skb(sk, skb);
+               sock_put(sk);
+               /* a return value > 0 means to resubmit the input, but
+@@ -1487,7 +1494,7 @@ struct proto udp_prot = {
+       .sendmsg           = udp_sendmsg,
+       .recvmsg           = udp_recvmsg,
+       .sendpage          = udp_sendpage,
+-      .backlog_rcv       = udp_queue_rcv_skb,
++      .backlog_rcv       = __udp_queue_rcv_skb,
+       .hash              = udp_lib_hash,
+       .unhash            = udp_lib_unhash,
+       .get_port          = udp_v4_get_port,
index 48236074e99bf5165e6e6b8698d87065f2ad2efd..fe2f227eeb9c97cc3c291680399edd9db23b00c4 100644 (file)
@@ -48,3 +48,12 @@ timer-fix-09.patch
 timer-fix-10.patch
 timer-fix-11.patch
 pcmcia-fix-broken-abuse-of-dev-driver_data.patch
+0001-af_key-Free-dumping-state-on-socket-close.patch
+0002-XFRM-IPv6-initialize-ip6_dst_blackhole_ops.kmem_cac.patch
+0003-ipv6-Fix-OOPS-in-ip6_dst_lookup_tail.patch
+0004-niu-panic-on-reset.patch
+0005-netlink-fix-overrun-in-attribute-iteration.patch
+0006-ipsec-Fix-pskb_expand_head-corruption-in-xfrm_state.patch
+0007-sctp-do-not-enable-peer-features-if-we-can-t-do-the.patch
+0008-sctp-Fix-oops-when-INIT-ACK-indicates-that-peer-doe.patch
+0009-udp-Fix-rcv-socket-locking.patch