]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
networking patches for .26
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 3 Sep 2008 15:35:07 +0000 (08:35 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 3 Sep 2008 15:35:07 +0000 (08:35 -0700)
14 files changed:
queue-2.6.26/0001-AX.25-Fix-sysctl-registration-if-CONFIG_AX25_DAMA_.patch [new file with mode: 0644]
queue-2.6.26/0002-ipv6-Fix-OOPS-ip-f-inet6-route-get-fec0-1-linux.patch [new file with mode: 0644]
queue-2.6.26/0003-netns-Add-network-namespace-argument-to-rt6_fill_no.patch [new file with mode: 0644]
queue-2.6.26/0004-pkt_sched-Fix-return-value-corruption-in-HTB-and-TB.patch [new file with mode: 0644]
queue-2.6.26/0005-pkt_sched-Fix-actions-referencing.patch [new file with mode: 0644]
queue-2.6.26/0006-udp-Drop-socket-lock-for-encapsulated-packets.patch [new file with mode: 0644]
queue-2.6.26/0007-sctp-fix-potential-panics-in-the-SCTP-AUTH-API.patch [new file with mode: 0644]
queue-2.6.26/0008-sctp-add-verification-checks-to-SCTP_AUTH_KEY-optio.patch [new file with mode: 0644]
queue-2.6.26/0009-sch_prio-Fix-nla_parse_nested_compat-regression.patch [new file with mode: 0644]
queue-2.6.26/0010-net-Unbreak-userspace-which-includes-linux-mroute.h.patch [new file with mode: 0644]
queue-2.6.26/0011-sctp-correct-bounds-check-in-sctp_setsockopt_auth_k.patch [new file with mode: 0644]
queue-2.6.26/0012-sctp-fix-random-memory-dereference-with-SCTP_HMAC_I.patch [new file with mode: 0644]
queue-2.6.26/0013-ipsec-Fix-deadlock-in-xfrm_state-management.patch [new file with mode: 0644]
queue-2.6.26/series

diff --git a/queue-2.6.26/0001-AX.25-Fix-sysctl-registration-if-CONFIG_AX25_DAMA_.patch b/queue-2.6.26/0001-AX.25-Fix-sysctl-registration-if-CONFIG_AX25_DAMA_.patch
new file mode 100644 (file)
index 0000000..7e90371
--- /dev/null
@@ -0,0 +1,68 @@
+From 6960627457edff5313fb369cba645d5d5ab73e01 Mon Sep 17 00:00:00 2001
+From: Ralf Baechle <ralf@linux-mips.org>
+Date: Wed, 27 Aug 2008 22:28:53 -0700
+Subject: AX.25: Fix sysctl registration if !CONFIG_AX25_DAMA_SLAVE
+
+From: Ralf Baechle <ralf@linux-mips.org>
+
+[ Upstream commit ffb208479bd62ab26c29a242faeb1de1c6d5fcdc ]
+
+Since 49ffcf8f99e8d33ec8afb450956804af518fd788 ("sysctl: update
+sysctl_check_table") setting struct ctl_table.procname = NULL does no
+longer work as it used to the way the AX.25 code is expecting it to
+resulting in the AX.25 sysctl registration code to break if
+CONFIG_AX25_DAMA_SLAVE was not set as in some distribution kernels.
+Kernel releases from 2.6.24 are affected.
+
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ax25/sysctl_net_ax25.c |   14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+--- a/net/ax25/sysctl_net_ax25.c
++++ b/net/ax25/sysctl_net_ax25.c
+@@ -36,6 +36,7 @@ static struct ctl_path ax25_path[] = {
+       { .procname = "ax25", .ctl_name = NET_AX25, },
+       { }
+ };
++
+ static const ctl_table ax25_param_table[] = {
+       {
+               .ctl_name       = NET_AX25_IP_DEFAULT_MODE,
+@@ -167,6 +168,7 @@ static const ctl_table ax25_param_table[
+               .extra1         = &min_proto,
+               .extra2         = &max_proto
+       },
++#ifdef CONFIG_AX25_DAMA_SLAVE
+       {
+               .ctl_name       = NET_AX25_DAMA_SLAVE_TIMEOUT,
+               .procname       = "dama_slave_timeout",
+@@ -177,6 +179,8 @@ static const ctl_table ax25_param_table[
+               .extra1         = &min_ds_timeout,
+               .extra2         = &max_ds_timeout
+       },
++#endif
++
+       { .ctl_name = 0 }       /* that's all, folks! */
+ };
+@@ -210,16 +214,6 @@ void ax25_register_sysctl(void)
+               ax25_table[n].procname     = ax25_dev->dev->name;
+               ax25_table[n].mode         = 0555;
+-#ifndef CONFIG_AX25_DAMA_SLAVE
+-              /*
+-               * We do not wish to have a representation of this parameter
+-               * in /proc/sys/ when configured *not* to include the
+-               * AX.25 DAMA slave code, do we?
+-               */
+-
+-              child[AX25_VALUES_DS_TIMEOUT].procname = NULL;
+-#endif
+-
+               child[AX25_MAX_VALUES].ctl_name = 0;    /* just in case... */
+               for (k = 0; k < AX25_MAX_VALUES; k++)
diff --git a/queue-2.6.26/0002-ipv6-Fix-OOPS-ip-f-inet6-route-get-fec0-1-linux.patch b/queue-2.6.26/0002-ipv6-Fix-OOPS-ip-f-inet6-route-get-fec0-1-linux.patch
new file mode 100644 (file)
index 0000000..f03693e
--- /dev/null
@@ -0,0 +1,60 @@
+From faac03cead6146bddd3180678fff849a06705ab7 Mon Sep 17 00:00:00 2001
+From: Brian Haley <brian.haley@hp.com>
+Date: Wed, 27 Aug 2008 22:30:08 -0700
+Subject: ipv6: Fix OOPS, ip -f inet6 route get fec0::1, linux-2.6.26, ip6_route_output, rt6_fill_node+0x175
+
+From: Brian Haley <brian.haley@hp.com>
+
+[ Upstream commit 5e0115e500fe9dd2ca11e6f92db9123204f1327a ]
+
+Alexey Dobriyan wrote:
+> On Thu, Aug 07, 2008 at 07:00:56PM +0200, John Gumb wrote:
+>> Scenario: no ipv6 default route set.
+>
+>> # ip -f inet6 route get fec0::1
+>>
+>> BUG: unable to handle kernel NULL pointer dereference at 00000000
+>> IP: [<c0369b85>] rt6_fill_node+0x175/0x3b0
+>> EIP is at rt6_fill_node+0x175/0x3b0
+>
+> 0xffffffff80424dd3 is in rt6_fill_node (net/ipv6/route.c:2191).
+> 2186                    } else
+> 2187    #endif
+> 2188                            NLA_PUT_U32(skb, RTA_IIF, iif);
+> 2189            } else if (dst) {
+> 2190                    struct in6_addr saddr_buf;
+> 2191      ====>         if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev,
+>                                             ^^^^^^^^^^^^^^^^^^^^^^^^
+>                                                                                      NULL
+>
+> 2192                                           dst, 0, &saddr_buf) == 0)
+> 2193                            NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
+> 2194            }
+
+The commit that changed this can't be reverted easily, but the patch
+below works for me.
+
+Fix NULL de-reference in rt6_fill_node() when there's no IPv6 input
+device present in the dst entry.
+
+Signed-off-by: Brian Haley <brian.haley@hp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv6/route.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -2179,8 +2179,9 @@ static int rt6_fill_node(struct sk_buff 
+ #endif
+                       NLA_PUT_U32(skb, RTA_IIF, iif);
+       } else if (dst) {
++              struct inet6_dev *idev = ip6_dst_idev(&rt->u.dst);
+               struct in6_addr saddr_buf;
+-              if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev,
++              if (ipv6_dev_get_saddr(idev ? idev->dev : NULL,
+                                      dst, 0, &saddr_buf) == 0)
+                       NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
+       }
diff --git a/queue-2.6.26/0003-netns-Add-network-namespace-argument-to-rt6_fill_no.patch b/queue-2.6.26/0003-netns-Add-network-namespace-argument-to-rt6_fill_no.patch
new file mode 100644 (file)
index 0000000..81f19de
--- /dev/null
@@ -0,0 +1,192 @@
+From 9a6484bf4021520db69e2988cfacd162a8379dad Mon Sep 17 00:00:00 2001
+From: Brian Haley <brian.haley@hp.com>
+Date: Wed, 27 Aug 2008 22:30:52 -0700
+Subject: netns: Add network namespace argument to rt6_fill_node() and ipv6_dev_get_saddr()
+
+From: Brian Haley <brian.haley@hp.com>
+
+[ Upstream commit 191cd582500f49b32a63040fedeebb0168c720af ]
+
+ipv6_dev_get_saddr() blindly de-references dst_dev to get the network
+namespace, but some callers might pass NULL.  Change callers to pass a
+namespace pointer instead.
+
+Signed-off-by: Brian Haley <brian.haley@hp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/net/addrconf.h  |    3 ++-
+ include/net/ip6_route.h |    1 +
+ net/ipv6/addrconf.c     |    3 +--
+ net/ipv6/fib6_rules.c   |    3 ++-
+ net/ipv6/ip6_fib.c      |    1 +
+ net/ipv6/ip6_output.c   |    2 +-
+ net/ipv6/ndisc.c        |    2 +-
+ net/ipv6/route.c        |   12 +++++++-----
+ net/ipv6/xfrm6_policy.c |    4 +++-
+ net/sctp/ipv6.c         |    3 ++-
+ 10 files changed, 21 insertions(+), 13 deletions(-)
+
+--- a/include/net/addrconf.h
++++ b/include/net/addrconf.h
+@@ -80,7 +80,8 @@ extern struct inet6_ifaddr      *ipv6_ge
+                                                struct net_device *dev,
+                                                int strict);
+-extern int                    ipv6_dev_get_saddr(struct net_device *dev, 
++extern int                    ipv6_dev_get_saddr(struct net *net,
++                                             struct net_device *dev,
+                                              const struct in6_addr *daddr,
+                                              unsigned int srcprefs,
+                                              struct in6_addr *saddr);
+--- a/include/net/ip6_route.h
++++ b/include/net/ip6_route.h
+@@ -112,6 +112,7 @@ struct rt6_rtnl_dump_arg
+ {
+       struct sk_buff *skb;
+       struct netlink_callback *cb;
++      struct net *net;
+ };
+ extern int rt6_dump_route(struct rt6_info *rt, void *p_arg);
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1076,13 +1076,12 @@ out:
+       return ret;
+ }
+-int ipv6_dev_get_saddr(struct net_device *dst_dev,
++int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
+                      const struct in6_addr *daddr, unsigned int prefs,
+                      struct in6_addr *saddr)
+ {
+       struct ipv6_saddr_score scores[2],
+                               *score = &scores[0], *hiscore = &scores[1];
+-      struct net *net = dev_net(dst_dev);
+       struct ipv6_saddr_dst dst;
+       struct net_device *dev;
+       int dst_type;
+--- a/net/ipv6/fib6_rules.c
++++ b/net/ipv6/fib6_rules.c
+@@ -93,7 +93,8 @@ static int fib6_rule_action(struct fib_r
+                       if (flags & RT6_LOOKUP_F_SRCPREF_COA)
+                               srcprefs |= IPV6_PREFER_SRC_COA;
+-                      if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev,
++                      if (ipv6_dev_get_saddr(net,
++                                             ip6_dst_idev(&rt->u.dst)->dev,
+                                              &flp->fl6_dst, srcprefs,
+                                              &saddr))
+                               goto again;
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -380,6 +380,7 @@ static int inet6_dump_fib(struct sk_buff
+       arg.skb = skb;
+       arg.cb = cb;
++      arg.net = net;
+       w->args = &arg;
+       for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -925,7 +925,7 @@ static int ip6_dst_lookup_tail(struct so
+               goto out_err_release;
+       if (ipv6_addr_any(&fl->fl6_src)) {
+-              err = ipv6_dev_get_saddr(ip6_dst_idev(*dst)->dev,
++              err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev,
+                                        &fl->fl6_dst,
+                                        sk ? inet6_sk(sk)->srcprefs : 0,
+                                        &fl->fl6_src);
+--- a/net/ipv6/ndisc.c
++++ b/net/ipv6/ndisc.c
+@@ -549,7 +549,7 @@ static void ndisc_send_na(struct net_dev
+                       override = 0;
+               in6_ifa_put(ifp);
+       } else {
+-              if (ipv6_dev_get_saddr(dev, daddr,
++              if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
+                                      inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
+                                      &tmpaddr))
+                       return;
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -2098,7 +2098,8 @@ static inline size_t rt6_nlmsg_size(void
+              + nla_total_size(sizeof(struct rta_cacheinfo));
+ }
+-static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
++static int rt6_fill_node(struct net *net,
++                       struct sk_buff *skb, struct rt6_info *rt,
+                        struct in6_addr *dst, struct in6_addr *src,
+                        int iif, int type, u32 pid, u32 seq,
+                        int prefix, int nowait, unsigned int flags)
+@@ -2181,7 +2182,7 @@ static int rt6_fill_node(struct sk_buff 
+       } else if (dst) {
+               struct inet6_dev *idev = ip6_dst_idev(&rt->u.dst);
+               struct in6_addr saddr_buf;
+-              if (ipv6_dev_get_saddr(idev ? idev->dev : NULL,
++              if (ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
+                                      dst, 0, &saddr_buf) == 0)
+                       NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
+       }
+@@ -2226,7 +2227,8 @@ int rt6_dump_route(struct rt6_info *rt, 
+       } else
+               prefix = 0;
+-      return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
++      return rt6_fill_node(arg->net,
++                   arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
+                    NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq,
+                    prefix, 0, NLM_F_MULTI);
+ }
+@@ -2292,7 +2294,7 @@ static int inet6_rtm_getroute(struct sk_
+       rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl);
+       skb->dst = &rt->u.dst;
+-      err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
++      err = rt6_fill_node(net, skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
+                           RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
+                           nlh->nlmsg_seq, 0, 0, 0);
+       if (err < 0) {
+@@ -2319,7 +2321,7 @@ void inet6_rt_notify(int event, struct r
+       if (skb == NULL)
+               goto errout;
+-      err = rt6_fill_node(skb, rt, NULL, NULL, 0,
++      err = rt6_fill_node(net, skb, rt, NULL, NULL, 0,
+                               event, info->pid, seq, 0, 0, 0);
+       if (err < 0) {
+               /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -52,12 +52,14 @@ static struct dst_entry *xfrm6_dst_looku
+ static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
+ {
+       struct dst_entry *dst;
++      struct net_device *dev;
+       dst = xfrm6_dst_lookup(0, NULL, daddr);
+       if (IS_ERR(dst))
+               return -EHOSTUNREACH;
+-      ipv6_dev_get_saddr(ip6_dst_idev(dst)->dev,
++      dev = ip6_dst_idev(dst)->dev;
++      ipv6_dev_get_saddr(dev_net(dev), dev,
+                          (struct in6_addr *)&daddr->a6, 0,
+                          (struct in6_addr *)&saddr->a6);
+       dst_release(dst);
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -317,7 +317,8 @@ static void sctp_v6_get_saddr(struct sct
+                         __func__, asoc, dst, NIP6(daddr->v6.sin6_addr));
+       if (!asoc) {
+-              ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL,
++              ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)),
++                                 dst ? ip6_dst_idev(dst)->dev : NULL,
+                                  &daddr->v6.sin6_addr,
+                                  inet6_sk(&sk->inet.sk)->srcprefs,
+                                  &saddr->v6.sin6_addr);
diff --git a/queue-2.6.26/0004-pkt_sched-Fix-return-value-corruption-in-HTB-and-TB.patch b/queue-2.6.26/0004-pkt_sched-Fix-return-value-corruption-in-HTB-and-TB.patch
new file mode 100644 (file)
index 0000000..5887258
--- /dev/null
@@ -0,0 +1,83 @@
+From d63121b53730c03d4c2c32fbecc31aac031fca45 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Wed, 27 Aug 2008 22:35:56 -0700
+Subject: pkt_sched: Fix return value corruption in HTB and TBF.
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 69747650c814a8a79fef412c7416adf823293a3e ]
+
+Based upon a bug report by Josip Rodin.
+
+Packet schedulers should only return NET_XMIT_DROP iff
+the packet really was dropped.  If the packet does reach
+the device after we return NET_XMIT_DROP then TCP can
+crash because it depends upon the enqueue path return
+values being accurate.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/sched/sch_htb.c |   20 ++++++++++++--------
+ net/sched/sch_tbf.c |   11 ++---------
+ 2 files changed, 14 insertions(+), 17 deletions(-)
+
+--- a/net/sched/sch_htb.c
++++ b/net/sched/sch_htb.c
+@@ -595,11 +595,13 @@ static int htb_enqueue(struct sk_buff *s
+               kfree_skb(skb);
+               return ret;
+ #endif
+-      } else if (cl->un.leaf.q->enqueue(skb, cl->un.leaf.q) !=
++      } else if ((ret = cl->un.leaf.q->enqueue(skb, cl->un.leaf.q)) !=
+                  NET_XMIT_SUCCESS) {
+-              sch->qstats.drops++;
+-              cl->qstats.drops++;
+-              return NET_XMIT_DROP;
++              if (ret == NET_XMIT_DROP) {
++                      sch->qstats.drops++;
++                      cl->qstats.drops++;
++              }
++              return ret;
+       } else {
+               cl->bstats.packets +=
+                       skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1;
+@@ -639,11 +641,13 @@ static int htb_requeue(struct sk_buff *s
+               kfree_skb(skb);
+               return ret;
+ #endif
+-      } else if (cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q) !=
++      } else if ((ret = cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q)) !=
+                  NET_XMIT_SUCCESS) {
+-              sch->qstats.drops++;
+-              cl->qstats.drops++;
+-              return NET_XMIT_DROP;
++              if (ret == NET_XMIT_DROP) {
++                      sch->qstats.drops++;
++                      cl->qstats.drops++;
++              }
++              return ret;
+       } else
+               htb_activate(q, cl);
+--- a/net/sched/sch_tbf.c
++++ b/net/sched/sch_tbf.c
+@@ -123,15 +123,8 @@ static int tbf_enqueue(struct sk_buff *s
+       struct tbf_sched_data *q = qdisc_priv(sch);
+       int ret;
+-      if (skb->len > q->max_size) {
+-              sch->qstats.drops++;
+-#ifdef CONFIG_NET_CLS_ACT
+-              if (sch->reshape_fail == NULL || sch->reshape_fail(skb, sch))
+-#endif
+-                      kfree_skb(skb);
+-
+-              return NET_XMIT_DROP;
+-      }
++      if (skb->len > q->max_size)
++              return qdisc_reshape_fail(skb, sch);
+       if ((ret = q->qdisc->enqueue(skb, q->qdisc)) != 0) {
+               sch->qstats.drops++;
diff --git a/queue-2.6.26/0005-pkt_sched-Fix-actions-referencing.patch b/queue-2.6.26/0005-pkt_sched-Fix-actions-referencing.patch
new file mode 100644 (file)
index 0000000..fd5f2ed
--- /dev/null
@@ -0,0 +1,36 @@
+From e3e7b1a03cbd69e446791afa9c0196d73cf6f94b Mon Sep 17 00:00:00 2001
+From: Jamal Hadi Salim <hadi@cyberus.ca>
+Date: Wed, 27 Aug 2008 22:38:11 -0700
+Subject: [PATCH] pkt_sched: Fix actions referencing
+
+From: Jamal Hadi Salim <hadi@cyberus.ca>
+
+[ Upstream commit 76aab2c1eae491a5d73ac83deec97dd28ebac584 ]
+
+When an action is added several times with the same exact index
+it gets deleted on every even-numbered attempt.
+This fixes that issue.
+
+Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/sched/act_api.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/net/sched/act_api.c
++++ b/net/sched/act_api.c
+@@ -205,10 +205,9 @@ struct tcf_common *tcf_hash_check(u32 in
+ {
+       struct tcf_common *p = NULL;
+       if (index && (p = tcf_hash_lookup(index, hinfo)) != NULL) {
+-              if (bind) {
++              if (bind)
+                       p->tcfc_bindcnt++;
+-                      p->tcfc_refcnt++;
+-              }
++              p->tcfc_refcnt++;
+               a->priv = p;
+       }
+       return p;
diff --git a/queue-2.6.26/0006-udp-Drop-socket-lock-for-encapsulated-packets.patch b/queue-2.6.26/0006-udp-Drop-socket-lock-for-encapsulated-packets.patch
new file mode 100644 (file)
index 0000000..9486802
--- /dev/null
@@ -0,0 +1,86 @@
+From ea1b147e2aac639e6e8385399a21fca20b904acf Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Wed, 27 Aug 2008 22:40:04 -0700
+Subject: udp: Drop socket lock for encapsulated packets
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit d97106ea52aa57e63ff40d04479016836bbb5a4e ]
+
+The socket lock is there to protect the normal UDP receive path.
+Encapsulation UDP sockets don't need that protection.  In fact
+the locking is deadly for them as they may contain another UDP
+packet within, possibly with the same addresses.
+
+Also the nested bit was copied from TCP.  TCP needs it because
+of accept(2) spawning sockets.  This simply doesn't apply to UDP
+so I've removed it.
+
+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 |    6 ++++--
+ net/ipv6/udp.c |    6 +++---
+ 2 files changed, 7 insertions(+), 5 deletions(-)
+
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -988,7 +988,9 @@ 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);
+@@ -1087,7 +1089,7 @@ static int __udp4_lib_mcast_deliver(stru
+                       if (skb1) {
+                               int ret = 0;
+-                              bh_lock_sock_nested(sk);
++                              bh_lock_sock(sk);
+                               if (!sock_owned_by_user(sk))
+                                       ret = udp_queue_rcv_skb(sk, skb1);
+                               else
+@@ -1187,7 +1189,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, 
+       if (sk != NULL) {
+               int ret = 0;
+-              bh_lock_sock_nested(sk);
++              bh_lock_sock(sk);
+               if (!sock_owned_by_user(sk))
+                       ret = udp_queue_rcv_skb(sk, skb);
+               else
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -376,7 +376,7 @@ static int __udp6_lib_mcast_deliver(stru
+                                       uh->source, saddr, dif))) {
+               struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
+               if (buff) {
+-                      bh_lock_sock_nested(sk2);
++                      bh_lock_sock(sk2);
+                       if (!sock_owned_by_user(sk2))
+                               udpv6_queue_rcv_skb(sk2, buff);
+                       else
+@@ -384,7 +384,7 @@ static int __udp6_lib_mcast_deliver(stru
+                       bh_unlock_sock(sk2);
+               }
+       }
+-      bh_lock_sock_nested(sk);
++      bh_lock_sock(sk);
+       if (!sock_owned_by_user(sk))
+               udpv6_queue_rcv_skb(sk, skb);
+       else
+@@ -502,7 +502,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, 
+       /* deliver */
+-      bh_lock_sock_nested(sk);
++      bh_lock_sock(sk);
+       if (!sock_owned_by_user(sk))
+               udpv6_queue_rcv_skb(sk, skb);
+       else
diff --git a/queue-2.6.26/0007-sctp-fix-potential-panics-in-the-SCTP-AUTH-API.patch b/queue-2.6.26/0007-sctp-fix-potential-panics-in-the-SCTP-AUTH-API.patch
new file mode 100644 (file)
index 0000000..8d9344d
--- /dev/null
@@ -0,0 +1,251 @@
+From a12006354213203bf7fc2114286df9cbe848e234 Mon Sep 17 00:00:00 2001
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+Date: Wed, 27 Aug 2008 22:41:00 -0700
+Subject: sctp: fix potential panics in the SCTP-AUTH API.
+
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+
+[ Upstream commit 5e739d1752aca4e8f3e794d431503bfca3162df4 ]
+
+All of the SCTP-AUTH socket options could cause a panic
+if the extension is disabled and the API is envoked.
+
+Additionally, there were some additional assumptions that
+certain pointers would always be valid which may not
+always be the case.
+
+This patch hardens the API and address all of the crash
+scenarios.
+
+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/endpointola.c |    4 +-
+ net/sctp/socket.c      |   85 +++++++++++++++++++++++++++++++++++++------------
+ 2 files changed, 67 insertions(+), 22 deletions(-)
+
+--- a/net/sctp/endpointola.c
++++ b/net/sctp/endpointola.c
+@@ -103,6 +103,7 @@ static struct sctp_endpoint *sctp_endpoi
+               /* Initialize the CHUNKS parameter */
+               auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS;
++              auth_chunks->param_hdr.length = htons(sizeof(sctp_paramhdr_t));
+               /* If the Add-IP functionality is enabled, we must
+                * authenticate, ASCONF and ASCONF-ACK chunks
+@@ -110,8 +111,7 @@ static struct sctp_endpoint *sctp_endpoi
+               if (sctp_addip_enable) {
+                       auth_chunks->chunks[0] = SCTP_CID_ASCONF;
+                       auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK;
+-                      auth_chunks->param_hdr.length =
+-                                      htons(sizeof(sctp_paramhdr_t) + 2);
++                      auth_chunks->param_hdr.length += htons(2);
+               }
+       }
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -2965,6 +2965,9 @@ static int sctp_setsockopt_auth_chunk(st
+ {
+       struct sctp_authchunk val;
++      if (!sctp_auth_enable)
++              return -EACCES;
++
+       if (optlen != sizeof(struct sctp_authchunk))
+               return -EINVAL;
+       if (copy_from_user(&val, optval, optlen))
+@@ -2995,6 +2998,9 @@ static int sctp_setsockopt_hmac_ident(st
+       struct sctp_hmacalgo *hmacs;
+       int err;
++      if (!sctp_auth_enable)
++              return -EACCES;
++
+       if (optlen < sizeof(struct sctp_hmacalgo))
+               return -EINVAL;
+@@ -3033,6 +3039,9 @@ static int sctp_setsockopt_auth_key(stru
+       struct sctp_association *asoc;
+       int ret;
++      if (!sctp_auth_enable)
++              return -EACCES;
++
+       if (optlen <= sizeof(struct sctp_authkey))
+               return -EINVAL;
+@@ -3070,6 +3079,9 @@ static int sctp_setsockopt_active_key(st
+       struct sctp_authkeyid val;
+       struct sctp_association *asoc;
++      if (!sctp_auth_enable)
++              return -EACCES;
++
+       if (optlen != sizeof(struct sctp_authkeyid))
+               return -EINVAL;
+       if (copy_from_user(&val, optval, optlen))
+@@ -3095,6 +3107,9 @@ static int sctp_setsockopt_del_key(struc
+       struct sctp_authkeyid val;
+       struct sctp_association *asoc;
++      if (!sctp_auth_enable)
++              return -EACCES;
++
+       if (optlen != sizeof(struct sctp_authkeyid))
+               return -EINVAL;
+       if (copy_from_user(&val, optval, optlen))
+@@ -5053,19 +5068,29 @@ static int sctp_getsockopt_maxburst(stru
+ static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
+                                   char __user *optval, int __user *optlen)
+ {
++      struct sctp_hmacalgo  __user *p = (void __user *)optval;
+       struct sctp_hmac_algo_param *hmacs;
+-      __u16 param_len;
++      __u16 data_len = 0;
++      u32 num_idents;
++
++      if (!sctp_auth_enable)
++              return -EACCES;
+       hmacs = sctp_sk(sk)->ep->auth_hmacs_list;
+-      param_len = ntohs(hmacs->param_hdr.length);
++      data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t);
+-      if (len < param_len)
++      if (len < sizeof(struct sctp_hmacalgo) + data_len)
+               return -EINVAL;
++
++      len = sizeof(struct sctp_hmacalgo) + data_len;
++      num_idents = data_len / sizeof(u16);
++
+       if (put_user(len, optlen))
+               return -EFAULT;
+-      if (copy_to_user(optval, hmacs->hmac_ids, len))
++      if (put_user(num_idents, &p->shmac_num_idents))
++              return -EFAULT;
++      if (copy_to_user(p->shmac_idents, hmacs->hmac_ids, data_len))
+               return -EFAULT;
+-
+       return 0;
+ }
+@@ -5075,6 +5100,9 @@ static int sctp_getsockopt_active_key(st
+       struct sctp_authkeyid val;
+       struct sctp_association *asoc;
++      if (!sctp_auth_enable)
++              return -EACCES;
++
+       if (len < sizeof(struct sctp_authkeyid))
+               return -EINVAL;
+       if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid)))
+@@ -5089,6 +5117,12 @@ static int sctp_getsockopt_active_key(st
+       else
+               val.scact_keynumber = sctp_sk(sk)->ep->active_key_id;
++      len = sizeof(struct sctp_authkeyid);
++      if (put_user(len, optlen))
++              return -EFAULT;
++      if (copy_to_user(optval, &val, len))
++              return -EFAULT;
++
+       return 0;
+ }
+@@ -5099,13 +5133,16 @@ static int sctp_getsockopt_peer_auth_chu
+       struct sctp_authchunks val;
+       struct sctp_association *asoc;
+       struct sctp_chunks_param *ch;
+-      u32    num_chunks;
++      u32    num_chunks = 0;
+       char __user *to;
+-      if (len <= sizeof(struct sctp_authchunks))
++      if (!sctp_auth_enable)
++              return -EACCES;
++
++      if (len < sizeof(struct sctp_authchunks))
+               return -EINVAL;
+-      if (copy_from_user(&val, p, sizeof(struct sctp_authchunks)))
++      if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks)))
+               return -EFAULT;
+       to = p->gauth_chunks;
+@@ -5114,20 +5151,21 @@ static int sctp_getsockopt_peer_auth_chu
+               return -EINVAL;
+       ch = asoc->peer.peer_chunks;
++      if (!ch)
++              goto num;
+       /* See if the user provided enough room for all the data */
+       num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
+       if (len < num_chunks)
+               return -EINVAL;
+-      len = num_chunks;
+-      if (put_user(len, optlen))
++      if (copy_to_user(to, ch->chunks, num_chunks))
+               return -EFAULT;
++num:
++      len = sizeof(struct sctp_authchunks) + num_chunks;
++      if (put_user(len, optlen)) return -EFAULT;
+       if (put_user(num_chunks, &p->gauth_number_of_chunks))
+               return -EFAULT;
+-      if (copy_to_user(to, ch->chunks, len))
+-              return -EFAULT;
+-
+       return 0;
+ }
+@@ -5138,13 +5176,16 @@ static int sctp_getsockopt_local_auth_ch
+       struct sctp_authchunks val;
+       struct sctp_association *asoc;
+       struct sctp_chunks_param *ch;
+-      u32    num_chunks;
++      u32    num_chunks = 0;
+       char __user *to;
+-      if (len <= sizeof(struct sctp_authchunks))
++      if (!sctp_auth_enable)
++              return -EACCES;
++
++      if (len < sizeof(struct sctp_authchunks))
+               return -EINVAL;
+-      if (copy_from_user(&val, p, sizeof(struct sctp_authchunks)))
++      if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks)))
+               return -EFAULT;
+       to = p->gauth_chunks;
+@@ -5157,17 +5198,21 @@ static int sctp_getsockopt_local_auth_ch
+       else
+               ch = sctp_sk(sk)->ep->auth_chunk_list;
++      if (!ch)
++              goto num;
++
+       num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
+-      if (len < num_chunks)
++      if (len < sizeof(struct sctp_authchunks) + num_chunks)
+               return -EINVAL;
+-      len = num_chunks;
++      if (copy_to_user(to, ch->chunks, num_chunks))
++              return -EFAULT;
++num:
++      len = sizeof(struct sctp_authchunks) + num_chunks;
+       if (put_user(len, optlen))
+               return -EFAULT;
+       if (put_user(num_chunks, &p->gauth_number_of_chunks))
+               return -EFAULT;
+-      if (copy_to_user(to, ch->chunks, len))
+-              return -EFAULT;
+       return 0;
+ }
diff --git a/queue-2.6.26/0008-sctp-add-verification-checks-to-SCTP_AUTH_KEY-optio.patch b/queue-2.6.26/0008-sctp-add-verification-checks-to-SCTP_AUTH_KEY-optio.patch
new file mode 100644 (file)
index 0000000..09f1b12
--- /dev/null
@@ -0,0 +1,49 @@
+From c7064b2bd573a5bd2364e076878c753c5da50ee5 Mon Sep 17 00:00:00 2001
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+Date: Wed, 27 Aug 2008 22:41:52 -0700
+Subject: sctp: add verification checks to SCTP_AUTH_KEY option
+
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+
+[ Upstream commit 30c2235cbc477d4629983d440cdc4f496fec9246 ]
+
+The structure used for SCTP_AUTH_KEY option contains a
+length that needs to be verfied to prevent buffer overflow
+conditions.  Spoted by Eugene Teo <eteo@redhat.com>.
+
+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/auth.c   |    4 ++++
+ net/sctp/socket.c |    5 +++++
+ 2 files changed, 9 insertions(+)
+
+--- a/net/sctp/auth.c
++++ b/net/sctp/auth.c
+@@ -80,6 +80,10 @@ static struct sctp_auth_bytes *sctp_auth
+ {
+       struct sctp_auth_bytes *key;
++      /* Verify that we are not going to overflow INT_MAX */
++      if ((INT_MAX - key_len) < sizeof(struct sctp_auth_bytes))
++              return NULL;
++
+       /* Allocate the shared key */
+       key = kmalloc(sizeof(struct sctp_auth_bytes) + key_len, gfp);
+       if (!key)
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -3054,6 +3054,11 @@ static int sctp_setsockopt_auth_key(stru
+               goto out;
+       }
++      if (authkey->sca_keylength > optlen) {
++              ret = -EINVAL;
++              goto out;
++      }
++
+       asoc = sctp_id2assoc(sk, authkey->sca_assoc_id);
+       if (!asoc && authkey->sca_assoc_id && sctp_style(sk, UDP)) {
+               ret = -EINVAL;
diff --git a/queue-2.6.26/0009-sch_prio-Fix-nla_parse_nested_compat-regression.patch b/queue-2.6.26/0009-sch_prio-Fix-nla_parse_nested_compat-regression.patch
new file mode 100644 (file)
index 0000000..d1578ae
--- /dev/null
@@ -0,0 +1,54 @@
+From cb3b7106b526380da4133364ffb2cf187759d8ea Mon Sep 17 00:00:00 2001
+From: Thomas Graf <tgraf@suug.ch>
+Date: Wed, 3 Sep 2008 01:00:02 -0700
+Subject: sch_prio: Fix nla_parse_nested_compat() regression
+
+From: Thomas Graf <tgraf@suug.ch>
+
+[ No upstream commit, this is fixing code no longer in 2.6.27 ]
+
+nla_parse_nested_compat() was used to parse two different message
+formats in the netem and prio qdisc, when it was "fixed" to work
+with netem, it broke the multi queue support in the prio qdisc.
+Since the prio qdisc code in question is already removed in the
+development tree, this patch only fixes the regression in the
+stable tree.
+
+Based on original patch from Alexander H Duyck <alexander.h.duyck@intel.com>
+
+Signed-off-by: Thomas Graf <tgraf@suug.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/sched/sch_prio.c |   16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+--- a/net/sched/sch_prio.c
++++ b/net/sched/sch_prio.c
+@@ -228,14 +228,20 @@ static int prio_tune(struct Qdisc *sch, 
+ {
+       struct prio_sched_data *q = qdisc_priv(sch);
+       struct tc_prio_qopt *qopt;
+-      struct nlattr *tb[TCA_PRIO_MAX + 1];
++      struct nlattr *tb[TCA_PRIO_MAX + 1] = {0};
+       int err;
+       int i;
+-      err = nla_parse_nested_compat(tb, TCA_PRIO_MAX, opt, NULL, qopt,
+-                                    sizeof(*qopt));
+-      if (err < 0)
+-              return err;
++      qopt = nla_data(opt);
++      if (nla_len(opt) < sizeof(*qopt))
++              return -1;
++
++      if (nla_len(opt) >= sizeof(*qopt) + sizeof(struct nlattr)) {
++              err = nla_parse_nested(tb, TCA_PRIO_MAX,
++                                     (struct nlattr *) (qopt + 1), NULL);
++              if (err < 0)
++                      return err;
++      }
+       q->bands = qopt->bands;
+       /* If we're multiqueue, make sure the number of incoming bands
diff --git a/queue-2.6.26/0010-net-Unbreak-userspace-which-includes-linux-mroute.h.patch b/queue-2.6.26/0010-net-Unbreak-userspace-which-includes-linux-mroute.h.patch
new file mode 100644 (file)
index 0000000..a90b18e
--- /dev/null
@@ -0,0 +1,143 @@
+From c3725971d48033a43beb9e12ea4ae68cea5438c1 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Wed, 3 Sep 2008 01:01:01 -0700
+Subject: net: Unbreak userspace which includes linux/mroute.h
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 7c19a3d280297d43ef5ff7c6b205dc208a16d3d1 ]
+
+This essentially reverts two commits:
+
+1) 2e8046271f68198dd37451017c1a4a2432e4ec68 ("[IPV4] MROUTE: Move PIM
+   definitions to <linux/pim.h>.")
+
+and
+
+2) 80a9492a33dd7d852465625022d56ff76d62174d ("[IPV4] MROUTE: Adjust
+   include files for user-space.")
+
+which broke userpsace, in particular the XORP build as reported by
+Jose Calhariz, the debain package maintainer for XORP.
+
+Nothing originally in linux/mroute.h was exported to userspace
+ever, but some of this stuff started to be when it was moved into
+this new linux/pim.h, and that was wrong.  If we didn't provide these
+definitions for 10 years we can reasonable expect that applications
+defined this stuff locally or used GLIBC headers providing the
+protocol definitions.  And as such the only result of this can
+be conflict and userland build breakage.
+
+The commit #1 had such a short and terse commit message, that we
+cannot even know why such a move and set of new userland exports were
+even made.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/Kbuild   |    1 -
+ include/linux/mroute.h |   25 +++++++++++++++++++++----
+ include/linux/pim.h    |   45 ---------------------------------------------
+ 3 files changed, 21 insertions(+), 50 deletions(-)
+
+--- a/include/linux/Kbuild
++++ b/include/linux/Kbuild
+@@ -293,7 +293,6 @@ unifdef-y += parport.h
+ unifdef-y += patchkey.h
+ unifdef-y += pci.h
+ unifdef-y += personality.h
+-unifdef-y += pim.h
+ unifdef-y += pktcdvd.h
+ unifdef-y += pmu.h
+ unifdef-y += poll.h
+--- a/include/linux/mroute.h
++++ b/include/linux/mroute.h
+@@ -2,11 +2,7 @@
+ #define __LINUX_MROUTE_H
+ #include <linux/sockios.h>
+-#include <linux/types.h>
+-#ifdef __KERNEL__
+ #include <linux/in.h>
+-#endif
+-#include <linux/pim.h>
+ /*
+  *    Based on the MROUTING 3.5 defines primarily to keep
+@@ -214,6 +210,27 @@ struct mfc_cache 
+ #define IGMPMSG_WHOLEPKT      3               /* For PIM Register processing */
+ #ifdef __KERNEL__
++
++#define PIM_V1_VERSION                __constant_htonl(0x10000000)
++#define PIM_V1_REGISTER               1
++
++#define PIM_VERSION           2
++#define PIM_REGISTER          1
++
++#define PIM_NULL_REGISTER     __constant_htonl(0x40000000)
++
++/* PIMv2 register message header layout (ietf-draft-idmr-pimvsm-v2-00.ps */
++
++struct pimreghdr
++{
++      __u8    type;
++      __u8    reserved;
++      __be16  csum;
++      __be32  flags;
++};
++
++extern int pim_rcv_v1(struct sk_buff *);
++
+ struct rtmsg;
+ extern int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait);
+ #endif
+--- a/include/linux/pim.h
++++ /dev/null
+@@ -1,45 +0,0 @@
+-#ifndef __LINUX_PIM_H
+-#define __LINUX_PIM_H
+-
+-#include <asm/byteorder.h>
+-
+-#ifndef __KERNEL__
+-struct pim {
+-#if defined(__LITTLE_ENDIAN_BITFIELD)
+-      __u8    pim_type:4,             /* PIM message type */
+-              pim_ver:4;              /* PIM version */
+-#elif defined(__BIG_ENDIAN_BITFIELD)
+-      __u8    pim_ver:4;              /* PIM version */
+-              pim_type:4;             /* PIM message type */
+-#endif
+-      __u8    pim_rsv;                /* Reserved */
+-      __be16  pim_cksum;              /* Checksum */
+-};
+-
+-#define PIM_MINLEN            8
+-#endif
+-
+-/* Message types - V1 */
+-#define PIM_V1_VERSION                __constant_htonl(0x10000000)
+-#define PIM_V1_REGISTER               1
+-
+-/* Message types - V2 */
+-#define PIM_VERSION           2
+-#define PIM_REGISTER          1
+-
+-#if defined(__KERNEL__)
+-#define PIM_NULL_REGISTER     __constant_htonl(0x40000000)
+-
+-/* PIMv2 register message header layout (ietf-draft-idmr-pimvsm-v2-00.ps */
+-struct pimreghdr
+-{
+-      __u8    type;
+-      __u8    reserved;
+-      __be16  csum;
+-      __be32  flags;
+-};
+-
+-struct sk_buff;
+-extern int pim_rcv_v1(struct sk_buff *);
+-#endif
+-#endif
diff --git a/queue-2.6.26/0011-sctp-correct-bounds-check-in-sctp_setsockopt_auth_k.patch b/queue-2.6.26/0011-sctp-correct-bounds-check-in-sctp_setsockopt_auth_k.patch
new file mode 100644 (file)
index 0000000..884aae6
--- /dev/null
@@ -0,0 +1,35 @@
+From 7bcd9afb203f780afb7fddaf7604166912129c4e Mon Sep 17 00:00:00 2001
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+Date: Wed, 3 Sep 2008 01:02:19 -0700
+Subject: sctp: correct bounds check in sctp_setsockopt_auth_key
+
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+
+[ Upstream commit 328fc47ea0bcc27d9afa69c3ad6e52431cadd76c ]
+
+The bonds check to prevent buffer overlflow was not exactly
+right.  It still allowed overflow of up to 8 bytes which is
+sizeof(struct sctp_authkey).
+
+Since optlen is already checked against the size of that struct,
+we are guaranteed not to cause interger overflow either.
+
+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/socket.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -3054,7 +3054,7 @@ static int sctp_setsockopt_auth_key(stru
+               goto out;
+       }
+-      if (authkey->sca_keylength > optlen) {
++      if (authkey->sca_keylength > optlen - sizeof(struct sctp_authkey)) {
+               ret = -EINVAL;
+               goto out;
+       }
diff --git a/queue-2.6.26/0012-sctp-fix-random-memory-dereference-with-SCTP_HMAC_I.patch b/queue-2.6.26/0012-sctp-fix-random-memory-dereference-with-SCTP_HMAC_I.patch
new file mode 100644 (file)
index 0000000..187147f
--- /dev/null
@@ -0,0 +1,56 @@
+From ddfe8ddeda4fc1fa7cd39462af39d2d7b3423c3c Mon Sep 17 00:00:00 2001
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+Date: Wed, 3 Sep 2008 01:02:37 -0700
+Subject: sctp: fix random memory dereference with SCTP_HMAC_IDENT option.
+
+From: Vlad Yasevich <vladislav.yasevich@hp.com>
+
+[ Upstream commit d97240552cd98c4b07322f30f66fd9c3ba4171de ]
+
+The number of identifiers needs to be checked against the option
+length.  Also, the identifier index provided needs to be verified
+to make sure that it doesn't exceed the bounds of the array.
+
+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/auth.c   |    3 +++
+ net/sctp/socket.c |    6 ++++--
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+--- a/net/sctp/auth.c
++++ b/net/sctp/auth.c
+@@ -786,6 +786,9 @@ int sctp_auth_ep_set_hmacs(struct sctp_e
+       for (i = 0; i < hmacs->shmac_num_idents; i++) {
+               id = hmacs->shmac_idents[i];
++              if (id > SCTP_AUTH_HMAC_ID_MAX)
++                      return -EOPNOTSUPP;
++
+               if (SCTP_AUTH_HMAC_ID_SHA1 == id)
+                       has_sha1 = 1;
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -2996,6 +2996,7 @@ static int sctp_setsockopt_hmac_ident(st
+                                   int optlen)
+ {
+       struct sctp_hmacalgo *hmacs;
++      u32 idents;
+       int err;
+       if (!sctp_auth_enable)
+@@ -3013,8 +3014,9 @@ static int sctp_setsockopt_hmac_ident(st
+               goto out;
+       }
+-      if (hmacs->shmac_num_idents == 0 ||
+-          hmacs->shmac_num_idents > SCTP_AUTH_NUM_HMACS) {
++      idents = hmacs->shmac_num_idents;
++      if (idents == 0 || idents > SCTP_AUTH_NUM_HMACS ||
++          (idents * sizeof(u16)) > (optlen - sizeof(struct sctp_hmacalgo))) {
+               err = -EINVAL;
+               goto out;
+       }
diff --git a/queue-2.6.26/0013-ipsec-Fix-deadlock-in-xfrm_state-management.patch b/queue-2.6.26/0013-ipsec-Fix-deadlock-in-xfrm_state-management.patch
new file mode 100644 (file)
index 0000000..3f63d84
--- /dev/null
@@ -0,0 +1,154 @@
+From e0227ac0d1b681a0e9a809969861de078503056a Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Wed, 3 Sep 2008 01:03:39 -0700
+Subject: ipsec: Fix deadlock in xfrm_state management.
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 37b08e34a98c664bea86e3fae718ac45a46b7276 ]
+
+Ever since commit 4c563f7669c10a12354b72b518c2287ffc6ebfb3
+("[XFRM]: Speed up xfrm_policy and xfrm_state walking") it is
+illegal to call __xfrm_state_destroy (and thus xfrm_state_put())
+with xfrm_state_lock held.  If we do, we'll deadlock since we
+have the lock already and __xfrm_state_destroy() tries to take
+it again.
+
+Fix this by pushing the xfrm_state_put() calls after the lock
+is dropped.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/xfrm/xfrm_state.c |   32 +++++++++++++++++++++++---------
+ 1 file changed, 23 insertions(+), 9 deletions(-)
+
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -780,11 +780,13 @@ xfrm_state_find(xfrm_address_t *daddr, x
+ {
+       unsigned int h;
+       struct hlist_node *entry;
+-      struct xfrm_state *x, *x0;
++      struct xfrm_state *x, *x0, *to_put;
+       int acquire_in_progress = 0;
+       int error = 0;
+       struct xfrm_state *best = NULL;
++      to_put = NULL;
++
+       spin_lock_bh(&xfrm_state_lock);
+       h = xfrm_dst_hash(daddr, saddr, tmpl->reqid, family);
+       hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) {
+@@ -833,7 +835,7 @@ xfrm_state_find(xfrm_address_t *daddr, x
+               if (tmpl->id.spi &&
+                   (x0 = __xfrm_state_lookup(daddr, tmpl->id.spi,
+                                             tmpl->id.proto, family)) != NULL) {
+-                      xfrm_state_put(x0);
++                      to_put = x0;
+                       error = -EEXIST;
+                       goto out;
+               }
+@@ -849,7 +851,7 @@ xfrm_state_find(xfrm_address_t *daddr, x
+               error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid);
+               if (error) {
+                       x->km.state = XFRM_STATE_DEAD;
+-                      xfrm_state_put(x);
++                      to_put = x;
+                       x = NULL;
+                       goto out;
+               }
+@@ -870,7 +872,7 @@ xfrm_state_find(xfrm_address_t *daddr, x
+                       xfrm_hash_grow_check(x->bydst.next != NULL);
+               } else {
+                       x->km.state = XFRM_STATE_DEAD;
+-                      xfrm_state_put(x);
++                      to_put = x;
+                       x = NULL;
+                       error = -ESRCH;
+               }
+@@ -881,6 +883,8 @@ out:
+       else
+               *err = acquire_in_progress ? -EAGAIN : error;
+       spin_unlock_bh(&xfrm_state_lock);
++      if (to_put)
++              xfrm_state_put(to_put);
+       return x;
+ }
+@@ -1067,18 +1071,20 @@ static struct xfrm_state *__xfrm_find_ac
+ int xfrm_state_add(struct xfrm_state *x)
+ {
+-      struct xfrm_state *x1;
++      struct xfrm_state *x1, *to_put;
+       int family;
+       int err;
+       int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
+       family = x->props.family;
++      to_put = NULL;
++
+       spin_lock_bh(&xfrm_state_lock);
+       x1 = __xfrm_state_locate(x, use_spi, family);
+       if (x1) {
+-              xfrm_state_put(x1);
++              to_put = x1;
+               x1 = NULL;
+               err = -EEXIST;
+               goto out;
+@@ -1088,7 +1094,7 @@ int xfrm_state_add(struct xfrm_state *x)
+               x1 = __xfrm_find_acq_byseq(x->km.seq);
+               if (x1 && ((x1->id.proto != x->id.proto) ||
+                   xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) {
+-                      xfrm_state_put(x1);
++                      to_put = x1;
+                       x1 = NULL;
+               }
+       }
+@@ -1110,6 +1116,9 @@ out:
+               xfrm_state_put(x1);
+       }
++      if (to_put)
++              xfrm_state_put(to_put);
++
+       return err;
+ }
+ EXPORT_SYMBOL(xfrm_state_add);
+@@ -1269,10 +1278,12 @@ EXPORT_SYMBOL(xfrm_state_migrate);
+ int xfrm_state_update(struct xfrm_state *x)
+ {
+-      struct xfrm_state *x1;
++      struct xfrm_state *x1, *to_put;
+       int err;
+       int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
++      to_put = NULL;
++
+       spin_lock_bh(&xfrm_state_lock);
+       x1 = __xfrm_state_locate(x, use_spi, x->props.family);
+@@ -1281,7 +1292,7 @@ int xfrm_state_update(struct xfrm_state 
+               goto out;
+       if (xfrm_state_kern(x1)) {
+-              xfrm_state_put(x1);
++              to_put = x1;
+               err = -EEXIST;
+               goto out;
+       }
+@@ -1295,6 +1306,9 @@ int xfrm_state_update(struct xfrm_state 
+ out:
+       spin_unlock_bh(&xfrm_state_lock);
++      if (to_put)
++              xfrm_state_put(to_put);
++
+       if (err)
+               return err;
index ea787a885b397b0f05d572f8b2b12f9da00f825a..ba5199d25f2aeb52211a738db39243e24dbc1c7e 100644 (file)
@@ -17,3 +17,16 @@ drivers-char-random.c-fix-a-race-which-can-lead-to-a-bogus-bug.patch
 rtc_time_to_tm-fix-signed-unsigned-arithmetic.patch
 8250-improve-workaround-for-uarts-that-don-t-re-assert-thre-correctly.patch
 mm-make-setup_zone_migrate_reserve-aware-of-overlapping-nodes.patch
+0001-AX.25-Fix-sysctl-registration-if-CONFIG_AX25_DAMA_.patch
+0002-ipv6-Fix-OOPS-ip-f-inet6-route-get-fec0-1-linux.patch
+0003-netns-Add-network-namespace-argument-to-rt6_fill_no.patch
+0004-pkt_sched-Fix-return-value-corruption-in-HTB-and-TB.patch
+0005-pkt_sched-Fix-actions-referencing.patch
+0006-udp-Drop-socket-lock-for-encapsulated-packets.patch
+0007-sctp-fix-potential-panics-in-the-SCTP-AUTH-API.patch
+0008-sctp-add-verification-checks-to-SCTP_AUTH_KEY-optio.patch
+0009-sch_prio-Fix-nla_parse_nested_compat-regression.patch
+0010-net-Unbreak-userspace-which-includes-linux-mroute.h.patch
+0011-sctp-correct-bounds-check-in-sctp_setsockopt_auth_k.patch
+0012-sctp-fix-random-memory-dereference-with-SCTP_HMAC_I.patch
+0013-ipsec-Fix-deadlock-in-xfrm_state-management.patch