]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
-stable patches from the weekend, dups for 18/19:
authorChris Wright <chrisw@sous-sol.org>
Mon, 4 Dec 2006 23:28:36 +0000 (15:28 -0800)
committerChris Wright <chrisw@sous-sol.org>
Mon, 4 Dec 2006 23:28:36 +0000 (15:28 -0800)
 pkt_sched-act_gact-division-by-zero.patch
 sunhme-fix-for-sunhme-failures-on-x86.patch
18 only
 netfilter-ip_tables-revision-support-for-compat-code.patch
19 only
 ndisc-calculate-packet-length-correctly-for-allocation.patch (replaced)
 netfilter-bridge-netfilter-deal-with-martians-correctly.patch
 netfilter-fix-ip-ip6-arp-_tables-hook-validation.patch (in .18.5 already)
 netfilter-fix-iptables-compat-hook-validation.patch
 softmac-fix-unbalanced-mutex_lock-unlock-in-ieee80211softmac_wx_set_mlme.patch
 ib-ucm-fix-deadlock-in-cleanup.patch

13 files changed:
queue-2.6.18/netfilter-ip_tables-revision-support-for-compat-code.patch [new file with mode: 0644]
queue-2.6.18/pkt_sched-act_gact-division-by-zero.patch [new file with mode: 0644]
queue-2.6.18/series
queue-2.6.18/sunhme-fix-for-sunhme-failures-on-x86.patch [new file with mode: 0644]
queue-2.6.19/ib-ucm-fix-deadlock-in-cleanup.patch [new file with mode: 0644]
queue-2.6.19/ndisc-calculate-packet-length-correctly-for-allocation.patch
queue-2.6.19/netfilter-bridge-netfilter-deal-with-martians-correctly.patch [new file with mode: 0644]
queue-2.6.19/netfilter-fix-ip-ip6-arp-_tables-hook-validation.patch [new file with mode: 0644]
queue-2.6.19/netfilter-fix-iptables-compat-hook-validation.patch [new file with mode: 0644]
queue-2.6.19/pkt_sched-act_gact-division-by-zero.patch [new file with mode: 0644]
queue-2.6.19/series
queue-2.6.19/softmac-fix-unbalanced-mutex_lock-unlock-in-ieee80211softmac_wx_set_mlme.patch [new file with mode: 0644]
queue-2.6.19/sunhme-fix-for-sunhme-failures-on-x86.patch [new file with mode: 0644]

diff --git a/queue-2.6.18/netfilter-ip_tables-revision-support-for-compat-code.patch b/queue-2.6.18/netfilter-ip_tables-revision-support-for-compat-code.patch
new file mode 100644 (file)
index 0000000..64a7203
--- /dev/null
@@ -0,0 +1,45 @@
+From stable-bounces@linux.kernel.org  Fri Dec  1 20:19:52 2006
+Date: Fri, 01 Dec 2006 20:14:55 -0800 (PST)
+Message-Id: <20061201.201455.18148078.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: NETFILTER: ip_tables: revision support for compat code
+
+From: Patrick McHardy <kaber@trash.net>
+
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+commit 79030ed07de673e8451a03aecb9ada9f4d75d491
+tree 4ba8bd843c8bc95db0ea6877880b73d06da620e5
+parent bec71b162747708d4b45b0cd399b484f52f2901a
+author Patrick McHardy <kaber@trash.net> Wed, 20 Sep 2006 12:05:08 -0700
+committer David S. Miller <davem@sunset.davemloft.net> Fri, 22 Sep 2006 15:20:00 -0700
+
+ net/ipv4/netfilter/ip_tables.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.5.orig/net/ipv4/netfilter/ip_tables.c
++++ linux-2.6.18.5/net/ipv4/netfilter/ip_tables.c
+@@ -1989,6 +1989,8 @@ compat_get_entries(struct compat_ipt_get
+       return ret;
+ }
++static int do_ipt_get_ctl(struct sock *, int, void __user *, int *);
++
+ static int
+ compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
+ {
+@@ -2005,8 +2007,7 @@ compat_do_ipt_get_ctl(struct sock *sk, i
+               ret = compat_get_entries(user, len);
+               break;
+       default:
+-              duprintf("compat_do_ipt_get_ctl: unknown request %i\n", cmd);
+-              ret = -EINVAL;
++              ret = do_ipt_get_ctl(sk, cmd, user, len);
+       }
+       return ret;
+ }
diff --git a/queue-2.6.18/pkt_sched-act_gact-division-by-zero.patch b/queue-2.6.18/pkt_sched-act_gact-division-by-zero.patch
new file mode 100644 (file)
index 0000000..4750614
--- /dev/null
@@ -0,0 +1,40 @@
+From stable-bounces@linux.kernel.org  Fri Dec  1 20:41:40 2006
+Date: Fri, 01 Dec 2006 20:36:44 -0800 (PST)
+Message-Id: <20061201.203644.26925555.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: PKT_SCHED act_gact: division by zero
+
+Not returning -EINVAL, because someone might want to use the value
+zero in some future gact_prob algorithm?
+
+Signed-off-by: Kim Nordlund <kim.nordlund@nokia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+
+---
+ net/sched/act_gact.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.5.orig/net/sched/act_gact.c
++++ linux-2.6.18.5/net/sched/act_gact.c
+@@ -54,14 +54,14 @@ static DEFINE_RWLOCK(gact_lock);
+ #ifdef CONFIG_GACT_PROB
+ static int gact_net_rand(struct tcf_gact *p)
+ {
+-      if (net_random()%p->pval)
++      if (!p->pval || net_random()%p->pval)
+               return p->action;
+       return p->paction;
+ }
+ static int gact_determ(struct tcf_gact *p)
+ {
+-      if (p->bstats.packets%p->pval)
++      if (!p->pval || p->bstats.packets%p->pval)
+               return p->action;
+       return p->paction;
+ }
index a263fbf59ee484d067c4bf041bc0bf993432fcbd..c1331e74b9002dd72d0980a9731cee97aef8c26d 100644 (file)
@@ -5,3 +5,6 @@ ebtables-deal-with-the-worst-case-behaviour-in-loop-checks.patch
 ebtables-prevent-wraparounds-in-checks-for-entry-components-sizes.patch
 net_sched-policer-restore-compatibility-with-old-iproute-binaries.patch
 dm-crypt-fix-data-corruption-with-dm-crypt-over-raid5.patch
+netfilter-ip_tables-revision-support-for-compat-code.patch
+pkt_sched-act_gact-division-by-zero.patch
+sunhme-fix-for-sunhme-failures-on-x86.patch
diff --git a/queue-2.6.18/sunhme-fix-for-sunhme-failures-on-x86.patch b/queue-2.6.18/sunhme-fix-for-sunhme-failures-on-x86.patch
new file mode 100644 (file)
index 0000000..5d25e4d
--- /dev/null
@@ -0,0 +1,40 @@
+From stable-bounces@linux.kernel.org  Sun Dec  3 19:41:54 2006
+Date: Sun, 03 Dec 2006 19:36:32 -0800 (PST)
+Message-Id: <20061203.193632.41634212.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Subject: SUNHME: Fix for sunhme failures on x86
+
+From: Jurij Smakov <jurij@wooyd.org>
+
+The following patch fixes the failure of sunhme drivers on x86 hosts
+due to missing pci_enable_device() and pci_set_master() calls, lost
+during code refactoring. It has been filed as bugzilla bug #7502 [0]
+and Debian bug #397460 [1].
+
+[0] http://bugzilla.kernel.org/show_bug.cgi?id=7502
+[1] http://bugs.debian.org/397460
+
+Signed-off-by: Jurij Smakov <jurij@wooyd.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+---
+ drivers/net/sunhme.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- linux-2.6.18.5.orig/drivers/net/sunhme.c
++++ linux-2.6.18.5/drivers/net/sunhme.c
+@@ -3012,6 +3012,11 @@ static int __devinit happy_meal_pci_prob
+ #endif
+       err = -ENODEV;
++
++      if (pci_enable_device(pdev))
++              goto err_out;
++      pci_set_master(pdev);
++
+       if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) {
+               qp = quattro_pci_find(pdev);
+               if (qp == NULL)
diff --git a/queue-2.6.19/ib-ucm-fix-deadlock-in-cleanup.patch b/queue-2.6.19/ib-ucm-fix-deadlock-in-cleanup.patch
new file mode 100644 (file)
index 0000000..431d6de
--- /dev/null
@@ -0,0 +1,44 @@
+From stable-bounces@linux.kernel.org  Mon Dec  4 08:50:32 2006
+Date: Mon, 4 Dec 2006 18:44:48 +0200
+From: "Michael S. Tsirkin" <mst@mellanox.co.il>
+To: stable@kernel.org, Roland Dreier <rolandd@cisco.com>, Sean Hefty <sean.hefty@intel.com>
+Message-ID: <20061204164448.GA15375@mellanox.co.il>
+Subject: IB/ucm: Fix deadlock in cleanup
+
+ib_ucm_cleanup_events() holds file_mutex while calling ib_destroy_cm_id().
+This can deadlock since ib_destroy_cm_id() flushes event handlers, and
+ib_ucm_event_handler() needs file_mutex, too.  Therefore, drop the
+file_mutex during the call to ib_destroy_cm_id().
+
+Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
+Signed-off-by: Roland Dreier <rolandd@cisco.com>
+Acked-by: Sean Hefty <sean.hefty@intel.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+
+Hello, -stable team!
+This patch backports commit f469b2626f48829c06e40ac799c1edf62b12048e to 2.6.19.
+Please consider it for 2.6.19.y - this fixes a deadlock reproduced here at Mellanox.
+
+---
+ drivers/infiniband/core/ucm.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- linux-2.6.19.orig/drivers/infiniband/core/ucm.c
++++ linux-2.6.19/drivers/infiniband/core/ucm.c
+@@ -161,12 +161,14 @@ static void ib_ucm_cleanup_events(struct
+                                   struct ib_ucm_event, ctx_list);
+               list_del(&uevent->file_list);
+               list_del(&uevent->ctx_list);
++              mutex_unlock(&ctx->file->file_mutex);
+               /* clear incoming connections. */
+               if (ib_ucm_new_cm_id(uevent->resp.event))
+                       ib_destroy_cm_id(uevent->cm_id);
+               kfree(uevent);
++              mutex_lock(&ctx->file->file_mutex);
+       }
+       mutex_unlock(&ctx->file->file_mutex);
+ }
index 8c13314a260e17ad08f01692d6a08aa3690a088c..c0ceaa32f7819c7618240d16f9157d5b4ea191f1 100644 (file)
@@ -1,57 +1,68 @@
-From stable-bounces@linux.kernel.org  Wed Nov 29 20:26:45 2006
-Date: Wed, 29 Nov 2006 20:21:40 -0800 (PST)
-Message-Id: <20061129.202140.23013142.davem@davemloft.net>
-To: stable@kernel.org
+From stable-bounces@linux.kernel.org  Sat Dec  2 21:09:10 2006
+Message-Id: <20061202.210406.112265194.davem@davemloft.net>
+Date: Sat, 02 Dec 2006 21:04:06 -0800 (PST)
 From: David Miller <davem@davemloft.net>
+To: stable@kernel.org
 Subject: [IPV6] NDISC: Calculate packet length correctly for allocation.
-    
+
 MAX_HEADER does not include the ipv6 header length in it,
 so we need to add it in explicitly.
 
+With help from YOSHIFUJI Hideaki.
+
 Signed-off-by: David S. Miller <davem@davemloft.net>
 Signed-off-by: Chris Wright <chrisw@sous-sol.org>
 ---
- net/ipv6/ndisc.c |   11 +++++++----
- 1 file changed, 7 insertions(+), 4 deletions(-)
+commit 6e38433357e2381bb278a418fb7e2fd201475101
+Author: David S. Miller <davem@sunset.davemloft.net>
+Date:   Sat Dec 2 21:00:06 2006 -0800
+
+ net/ipv6/ndisc.c |   16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
 
 --- linux-2.6.19.orig/net/ipv6/ndisc.c
 +++ linux-2.6.19/net/ipv6/ndisc.c
-@@ -441,7 +441,8 @@ static void ndisc_send_na(struct net_dev
-         struct sk_buff *skb;
-       int err;
--      len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
-+      len = sizeof(struct ipv6hdr) + sizeof(struct icmp6hdr) +
-+              sizeof(struct in6_addr);
+@@ -472,7 +472,9 @@ static void ndisc_send_na(struct net_dev
+                       inc_opt = 0;
+       }
  
-       /* for anycast or proxy, solicited_addr != src_addr */
-       ifp = ipv6_get_ifaddr(solicited_addr, dev, 1);
-@@ -556,7 +557,8 @@ void ndisc_send_ns(struct net_device *de
-       if (err < 0)
-               return;
+-      skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
++      skb = sock_alloc_send_skb(sk,
++                                (MAX_HEADER + sizeof(struct ipv6hdr) +
++                                 len + LL_RESERVED_SPACE(dev)),
+                                 1, &err);
  
--      len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
-+      len = sizeof(struct ipv6hdr) + sizeof(struct icmp6hdr) +
-+              sizeof(struct in6_addr);
-       send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
+       if (skb == NULL) {
+@@ -561,7 +563,9 @@ void ndisc_send_ns(struct net_device *de
        if (send_llinfo)
                len += ndisc_opt_addr_space(dev);
-@@ -632,7 +634,7 @@ void ndisc_send_rs(struct net_device *de
-       if (err < 0)
-               return;
  
--      len = sizeof(struct icmp6hdr);
-+      len = sizeof(struct ipv6hdr) + sizeof(struct icmp6hdr);
+-      skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
++      skb = sock_alloc_send_skb(sk,
++                                (MAX_HEADER + sizeof(struct ipv6hdr) +
++                                 len + LL_RESERVED_SPACE(dev)),
+                                 1, &err);
+       if (skb == NULL) {
+               ND_PRINTK0(KERN_ERR
+@@ -636,7 +640,9 @@ void ndisc_send_rs(struct net_device *de
        if (dev->addr_len)
                len += ndisc_opt_addr_space(dev);
  
-@@ -1381,7 +1383,8 @@ void ndisc_send_redirect(struct sk_buff 
-                        struct in6_addr *target)
- {
-       struct sock *sk = ndisc_socket->sk;
--      int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
-+      int len = sizeof(struct ipv6hdr) + sizeof(struct icmp6hdr) +
-+              2 * sizeof(struct in6_addr);
-       struct sk_buff *buff;
-       struct icmp6hdr *icmph;
-       struct in6_addr saddr_buf;
+-        skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
++        skb = sock_alloc_send_skb(sk,
++                                (MAX_HEADER + sizeof(struct ipv6hdr) +
++                                 len + LL_RESERVED_SPACE(dev)),
+                                 1, &err);
+       if (skb == NULL) {
+               ND_PRINTK0(KERN_ERR
+@@ -1446,7 +1452,9 @@ void ndisc_send_redirect(struct sk_buff 
+       rd_len &= ~0x7;
+       len += rd_len;
+-      buff = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev),
++      buff = sock_alloc_send_skb(sk,
++                                 (MAX_HEADER + sizeof(struct ipv6hdr) +
++                                  len + LL_RESERVED_SPACE(dev)),
+                                  1, &err);
+       if (buff == NULL) {
+               ND_PRINTK0(KERN_ERR
diff --git a/queue-2.6.19/netfilter-bridge-netfilter-deal-with-martians-correctly.patch b/queue-2.6.19/netfilter-bridge-netfilter-deal-with-martians-correctly.patch
new file mode 100644 (file)
index 0000000..2175bbf
--- /dev/null
@@ -0,0 +1,124 @@
+From stable-bounces@linux.kernel.org  Mon Dec  4 03:27:33 2006
+From: Patrick McHardy <kaber@trash.net>
+To: stable@kernel.org
+Message-Id: <20061204112520.14395.14674.sendpatchset@localhost.localdomain>
+Date: Mon,  4 Dec 2006 12:22:10 +0100 (MET)
+Cc: Patrick McHardy <kaber@trash.net>, davem@davemloft.net
+Subject: NETFILTER: bridge netfilter: deal with martians correctly
+
+From: Bart De Schuymer <bdschuym@pandora.be>
+
+The attached patch resolves an issue where a IP DNATed packet with a
+martian source is forwarded while it's better to drop it. It also
+resolves messages complaining about ip forwarding being disabled while
+it's actually enabled. Thanks to lepton <ytht.net@gmail.com> for
+reporting this problem.
+
+This is probably a candidate for the -stable release.
+
+Signed-off-by: Bart De Schuymer <bdschuym@pandora.be>
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+commit bb01f827bae980efdecc33fbcdc1b90f1c355b3e
+tree 432a8f2843b47ccac094efea35da6f19731ed834
+parent 14f5487cb9bd34cd59360d2cac7dccac9b27e8ce
+author Bart De Schuymer <bdschuym@pandora.be> Mon, 04 Dec 2006 12:19:46 +0100
+committer Patrick McHardy <kaber@trash.net> Mon, 04 Dec 2006 12:19:46 +0100
+
+ net/bridge/br_netfilter.c |   36 ++++++++++++++++++++++++++++--------
+ 1 file changed, 28 insertions(+), 8 deletions(-)
+
+--- linux-2.6.19.orig/net/bridge/br_netfilter.c
++++ linux-2.6.19/net/bridge/br_netfilter.c
+@@ -34,6 +34,7 @@
+ #include <linux/netfilter_ipv6.h>
+ #include <linux/netfilter_arp.h>
+ #include <linux/in_route.h>
++#include <linux/inetdevice.h>
+ #include <net/ip.h>
+ #include <net/ipv6.h>
+@@ -222,10 +223,14 @@ static void __br_dnat_complain(void)
+  *
+  * Otherwise, the packet is considered to be routed and we just
+  * change the destination MAC address so that the packet will
+- * later be passed up to the IP stack to be routed.
++ * later be passed up to the IP stack to be routed. For a redirected
++ * packet, ip_route_input() will give back the localhost as output device,
++ * which differs from the bridge device.
+  *
+  * Let us now consider the case that ip_route_input() fails:
+  *
++ * This can be because the destination address is martian, in which case
++ * the packet will be dropped.
+  * After a "echo '0' > /proc/sys/net/ipv4/ip_forward" ip_route_input()
+  * will fail, while __ip_route_output_key() will return success. The source
+  * address for __ip_route_output_key() is set to zero, so __ip_route_output_key
+@@ -238,7 +243,8 @@ static void __br_dnat_complain(void)
+  *
+  * --Lennert, 20020411
+  * --Bart, 20020416 (updated)
+- * --Bart, 20021007 (updated) */
++ * --Bart, 20021007 (updated)
++ * --Bart, 20062711 (updated) */
+ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
+ {
+       if (skb->pkt_type == PACKET_OTHERHOST) {
+@@ -265,15 +271,15 @@ static int br_nf_pre_routing_finish(stru
+       struct net_device *dev = skb->dev;
+       struct iphdr *iph = skb->nh.iph;
+       struct nf_bridge_info *nf_bridge = skb->nf_bridge;
++      int err;
+       if (nf_bridge->mask & BRNF_PKT_TYPE) {
+               skb->pkt_type = PACKET_OTHERHOST;
+               nf_bridge->mask ^= BRNF_PKT_TYPE;
+       }
+       nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
+-
+       if (dnat_took_place(skb)) {
+-              if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) {
++              if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
+                       struct rtable *rt;
+                       struct flowi fl = {
+                               .nl_u = {
+@@ -284,19 +290,33 @@ static int br_nf_pre_routing_finish(stru
+                               },
+                               .proto = 0,
+                       };
++                      struct in_device *in_dev = in_dev_get(dev);
++
++                      /* If err equals -EHOSTUNREACH the error is due to a
++                       * martian destination or due to the fact that
++                       * forwarding is disabled. For most martian packets,
++                       * ip_route_output_key() will fail. It won't fail for 2 types of
++                       * martian destinations: loopback destinations and destination
++                       * 0.0.0.0. In both cases the packet will be dropped because the
++                       * destination is the loopback device and not the bridge. */
++                      if (err != -EHOSTUNREACH || !in_dev || IN_DEV_FORWARD(in_dev))
++                              goto free_skb;
+                       if (!ip_route_output_key(&rt, &fl)) {
+                               /* - Bridged-and-DNAT'ed traffic doesn't
+-                               *   require ip_forwarding.
+-                               * - Deal with redirected traffic. */
+-                              if (((struct dst_entry *)rt)->dev == dev ||
+-                                  rt->rt_type == RTN_LOCAL) {
++                               *   require ip_forwarding. */
++                              if (((struct dst_entry *)rt)->dev == dev) {
+                                       skb->dst = (struct dst_entry *)rt;
+                                       goto bridged_dnat;
+                               }
++                              /* we are sure that forwarding is disabled, so printing
++                               * this message is no problem. Note that the packet could
++                               * still have a martian destination address, in which case
++                               * the packet could be dropped even if forwarding were enabled */
+                               __br_dnat_complain();
+                               dst_release((struct dst_entry *)rt);
+                       }
++free_skb:
+                       kfree_skb(skb);
+                       return 0;
+               } else {
diff --git a/queue-2.6.19/netfilter-fix-ip-ip6-arp-_tables-hook-validation.patch b/queue-2.6.19/netfilter-fix-ip-ip6-arp-_tables-hook-validation.patch
new file mode 100644 (file)
index 0000000..114b0a3
--- /dev/null
@@ -0,0 +1,371 @@
+From stable-bounces@linux.kernel.org  Mon Dec  4 03:27:25 2006
+From: Patrick McHardy <kaber@trash.net>
+To: stable@kernel.org
+Message-Id: <20061204112517.14395.51777.sendpatchset@localhost.localdomain>
+Date: Mon,  4 Dec 2006 12:22:07 +0100 (MET)
+Cc: Patrick McHardy <kaber@trash.net>, davem@davemloft.net
+Subject: NETFILTER: Fix {ip, ip6, arp}_tables hook validation
+
+From: Dmitry Mishin <dim@openvz.org>
+
+Commit 590bdf7fd2292b47c428111cb1360e312eff207e introduced a regression
+in match/target hook validation. mark_source_chains builds a bitmask
+for each rule representing the hooks it can be reached from, which is
+then used by the matches and targets to make sure they are only called
+from valid hooks. The patch moved the match/target specific validation
+before the mark_source_chains call, at which point the mask is always zero.
+
+This patch returns back to the old order and moves the standard checks
+to mark_source_chains. This allows to get rid of a special case for
+standard targets as a nice side-effect.
+
+Signed-off-by: Dmitry Mishin <dim@openvz.org>
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+commit 756c508367e95d6f963502e4feecb8c76aeee332
+tree 2be0ffb477e890a713eb48f3993a2f425baf5683
+parent 0215ffb08ce99e2bb59eca114a99499a4d06e704
+author Dmitry Mishin <dim@openvz.org> Mon, 04 Dec 2006 12:19:27 +0100
+committer Patrick McHardy <kaber@trash.net> Mon, 04 Dec 2006 12:19:27 +0100
+
+ net/ipv4/netfilter/arp_tables.c |   48 ++++++++++++++--------------
+ net/ipv4/netfilter/ip_tables.c  |   68 ++++++++++++++--------------------------
+ net/ipv6/netfilter/ip6_tables.c |   59 +++++++++++++---------------------
+ 3 files changed, 72 insertions(+), 103 deletions(-)
+
+--- linux-2.6.19.orig/net/ipv4/netfilter/arp_tables.c
++++ linux-2.6.19/net/ipv4/netfilter/arp_tables.c
+@@ -375,6 +375,13 @@ static int mark_source_chains(struct xt_
+                           && unconditional(&e->arp)) {
+                               unsigned int oldpos, size;
++                              if (t->verdict < -NF_MAX_VERDICT - 1) {
++                                      duprintf("mark_source_chains: bad "
++                                              "negative verdict (%i)\n",
++                                                              t->verdict);
++                                      return 0;
++                              }
++
+                               /* Return: backtrack through the last
+                                * big jump.
+                                */
+@@ -404,6 +411,14 @@ static int mark_source_chains(struct xt_
+                               if (strcmp(t->target.u.user.name,
+                                          ARPT_STANDARD_TARGET) == 0
+                                   && newpos >= 0) {
++                                      if (newpos > newinfo->size -
++                                              sizeof(struct arpt_entry)) {
++                                              duprintf("mark_source_chains: "
++                                                      "bad verdict (%i)\n",
++                                                              newpos);
++                                              return 0;
++                                      }
++
+                                       /* This a jump; chase it. */
+                                       duprintf("Jump rule %u -> %u\n",
+                                                pos, newpos);
+@@ -426,8 +441,6 @@ static int mark_source_chains(struct xt_
+ static inline int standard_check(const struct arpt_entry_target *t,
+                                unsigned int max_offset)
+ {
+-      struct arpt_standard_target *targ = (void *)t;
+-
+       /* Check standard info. */
+       if (t->u.target_size
+           != ARPT_ALIGN(sizeof(struct arpt_standard_target))) {
+@@ -437,18 +450,6 @@ static inline int standard_check(const s
+               return 0;
+       }
+-      if (targ->verdict >= 0
+-          && targ->verdict > max_offset - sizeof(struct arpt_entry)) {
+-              duprintf("arpt_standard_check: bad verdict (%i)\n",
+-                       targ->verdict);
+-              return 0;
+-      }
+-
+-      if (targ->verdict < -NF_MAX_VERDICT - 1) {
+-              duprintf("arpt_standard_check: bad negative verdict (%i)\n",
+-                       targ->verdict);
+-              return 0;
+-      }
+       return 1;
+ }
+@@ -627,18 +628,20 @@ static int translate_table(const char *n
+               }
+       }
++      if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
++              duprintf("Looping hook\n");
++              return -ELOOP;
++      }
++
+       /* Finally, each sanity check must pass */
+       i = 0;
+       ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
+                                check_entry, name, size, &i);
+-      if (ret != 0)
+-              goto cleanup;
+-
+-      ret = -ELOOP;
+-      if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
+-              duprintf("Looping hook\n");
+-              goto cleanup;
++      if (ret != 0) {
++              ARPT_ENTRY_ITERATE(entry0, newinfo->size,
++                              cleanup_entry, &i);
++              return ret;
+       }
+       /* And one copy for every other CPU */
+@@ -647,9 +650,6 @@ static int translate_table(const char *n
+                       memcpy(newinfo->entries[i], entry0, newinfo->size);
+       }
+-      return 0;
+-cleanup:
+-      ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
+       return ret;
+ }
+--- linux-2.6.19.orig/net/ipv4/netfilter/ip_tables.c
++++ linux-2.6.19/net/ipv4/netfilter/ip_tables.c
+@@ -401,6 +401,13 @@ mark_source_chains(struct xt_table_info 
+                           && unconditional(&e->ip)) {
+                               unsigned int oldpos, size;
++                              if (t->verdict < -NF_MAX_VERDICT - 1) {
++                                      duprintf("mark_source_chains: bad "
++                                              "negative verdict (%i)\n",
++                                                              t->verdict);
++                                      return 0;
++                              }
++
+                               /* Return: backtrack through the last
+                                  big jump. */
+                               do {
+@@ -438,6 +445,13 @@ mark_source_chains(struct xt_table_info 
+                               if (strcmp(t->target.u.user.name,
+                                          IPT_STANDARD_TARGET) == 0
+                                   && newpos >= 0) {
++                                      if (newpos > newinfo->size -
++                                              sizeof(struct ipt_entry)) {
++                                              duprintf("mark_source_chains: "
++                                                      "bad verdict (%i)\n",
++                                                              newpos);
++                                              return 0;
++                                      }
+                                       /* This a jump; chase it. */
+                                       duprintf("Jump rule %u -> %u\n",
+                                                pos, newpos);
+@@ -470,27 +484,6 @@ cleanup_match(struct ipt_entry_match *m,
+ }
+ static inline int
+-standard_check(const struct ipt_entry_target *t,
+-             unsigned int max_offset)
+-{
+-      struct ipt_standard_target *targ = (void *)t;
+-
+-      /* Check standard info. */
+-      if (targ->verdict >= 0
+-          && targ->verdict > max_offset - sizeof(struct ipt_entry)) {
+-              duprintf("ipt_standard_check: bad verdict (%i)\n",
+-                       targ->verdict);
+-              return 0;
+-      }
+-      if (targ->verdict < -NF_MAX_VERDICT - 1) {
+-              duprintf("ipt_standard_check: bad negative verdict (%i)\n",
+-                       targ->verdict);
+-              return 0;
+-      }
+-      return 1;
+-}
+-
+-static inline int
+ check_match(struct ipt_entry_match *m,
+           const char *name,
+           const struct ipt_ip *ip,
+@@ -576,12 +569,7 @@ check_entry(struct ipt_entry *e, const c
+       if (ret)
+               goto err;
+-      if (t->u.kernel.target == &ipt_standard_target) {
+-              if (!standard_check(t, size)) {
+-                      ret = -EINVAL;
+-                      goto err;
+-              }
+-      } else if (t->u.kernel.target->checkentry
++      if (t->u.kernel.target->checkentry
+                  && !t->u.kernel.target->checkentry(name, e, target, t->data,
+                                                     e->comefrom)) {
+               duprintf("ip_tables: check failed for `%s'.\n",
+@@ -718,17 +706,19 @@ translate_table(const char *name,
+               }
+       }
++      if (!mark_source_chains(newinfo, valid_hooks, entry0))
++              return -ELOOP;
++
+       /* Finally, each sanity check must pass */
+       i = 0;
+       ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
+                               check_entry, name, size, &i);
+-      if (ret != 0)
+-              goto cleanup;
+-
+-      ret = -ELOOP;
+-      if (!mark_source_chains(newinfo, valid_hooks, entry0))
+-              goto cleanup;
++      if (ret != 0) {
++              IPT_ENTRY_ITERATE(entry0, newinfo->size,
++                              cleanup_entry, &i);
++              return ret;
++      }
+       /* And one copy for every other CPU */
+       for_each_possible_cpu(i) {
+@@ -736,9 +726,6 @@ translate_table(const char *name,
+                       memcpy(newinfo->entries[i], entry0, newinfo->size);
+       }
+-      return 0;
+-cleanup:
+-      IPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
+       return ret;
+ }
+@@ -1591,18 +1578,13 @@ static int compat_copy_entry_from_user(s
+       if (ret)
+               goto err;
+-      ret = -EINVAL;
+-      if (t->u.kernel.target == &ipt_standard_target) {
+-              if (!standard_check(t, *size))
+-                      goto err;
+-      } else if (t->u.kernel.target->checkentry
++      if (t->u.kernel.target->checkentry
+                  && !t->u.kernel.target->checkentry(name, de, target,
+                                                     t->data, de->comefrom)) {
+               duprintf("ip_tables: compat: check failed for `%s'.\n",
+                        t->u.kernel.target->name);
+-              goto err;
++              ret = -EINVAL;
+       }
+-      ret = 0;
+ err:
+       return ret;
+ }
+--- linux-2.6.19.orig/net/ipv6/netfilter/ip6_tables.c
++++ linux-2.6.19/net/ipv6/netfilter/ip6_tables.c
+@@ -440,6 +440,13 @@ mark_source_chains(struct xt_table_info 
+                           && unconditional(&e->ipv6)) {
+                               unsigned int oldpos, size;
++                              if (t->verdict < -NF_MAX_VERDICT - 1) {
++                                      duprintf("mark_source_chains: bad "
++                                              "negative verdict (%i)\n",
++                                                              t->verdict);
++                                      return 0;
++                              }
++
+                               /* Return: backtrack through the last
+                                  big jump. */
+                               do {
+@@ -477,6 +484,13 @@ mark_source_chains(struct xt_table_info 
+                               if (strcmp(t->target.u.user.name,
+                                          IP6T_STANDARD_TARGET) == 0
+                                   && newpos >= 0) {
++                                      if (newpos > newinfo->size -
++                                              sizeof(struct ip6t_entry)) {
++                                              duprintf("mark_source_chains: "
++                                                      "bad verdict (%i)\n",
++                                                              newpos);
++                                              return 0;
++                                      }
+                                       /* This a jump; chase it. */
+                                       duprintf("Jump rule %u -> %u\n",
+                                                pos, newpos);
+@@ -509,27 +523,6 @@ cleanup_match(struct ip6t_entry_match *m
+ }
+ static inline int
+-standard_check(const struct ip6t_entry_target *t,
+-             unsigned int max_offset)
+-{
+-      struct ip6t_standard_target *targ = (void *)t;
+-
+-      /* Check standard info. */
+-      if (targ->verdict >= 0
+-          && targ->verdict > max_offset - sizeof(struct ip6t_entry)) {
+-              duprintf("ip6t_standard_check: bad verdict (%i)\n",
+-                       targ->verdict);
+-              return 0;
+-      }
+-      if (targ->verdict < -NF_MAX_VERDICT - 1) {
+-              duprintf("ip6t_standard_check: bad negative verdict (%i)\n",
+-                       targ->verdict);
+-              return 0;
+-      }
+-      return 1;
+-}
+-
+-static inline int
+ check_match(struct ip6t_entry_match *m,
+           const char *name,
+           const struct ip6t_ip6 *ipv6,
+@@ -616,12 +609,7 @@ check_entry(struct ip6t_entry *e, const 
+       if (ret)
+               goto err;
+-      if (t->u.kernel.target == &ip6t_standard_target) {
+-              if (!standard_check(t, size)) {
+-                      ret = -EINVAL;
+-                      goto err;
+-              }
+-      } else if (t->u.kernel.target->checkentry
++      if (t->u.kernel.target->checkentry
+                  && !t->u.kernel.target->checkentry(name, e, target, t->data,
+                                                     e->comefrom)) {
+               duprintf("ip_tables: check failed for `%s'.\n",
+@@ -758,17 +746,19 @@ translate_table(const char *name,
+               }
+       }
++      if (!mark_source_chains(newinfo, valid_hooks, entry0))
++              return -ELOOP;
++
+       /* Finally, each sanity check must pass */
+       i = 0;
+       ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
+                               check_entry, name, size, &i);
+-      if (ret != 0)
+-              goto cleanup;
+-
+-      ret = -ELOOP;
+-      if (!mark_source_chains(newinfo, valid_hooks, entry0))
+-              goto cleanup;
++      if (ret != 0) {
++              IP6T_ENTRY_ITERATE(entry0, newinfo->size,
++                                 cleanup_entry, &i);
++              return ret;
++      }
+       /* And one copy for every other CPU */
+       for_each_possible_cpu(i) {
+@@ -777,9 +767,6 @@ translate_table(const char *name,
+       }
+       return 0;
+-cleanup:
+-      IP6T_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
+-      return ret;
+ }
+ /* Gets counters. */
diff --git a/queue-2.6.19/netfilter-fix-iptables-compat-hook-validation.patch b/queue-2.6.19/netfilter-fix-iptables-compat-hook-validation.patch
new file mode 100644 (file)
index 0000000..b22bbc0
--- /dev/null
@@ -0,0 +1,150 @@
+From stable-bounces@linux.kernel.org  Mon Dec  4 03:27:30 2006
+From: Patrick McHardy <kaber@trash.net>
+To: stable@kernel.org
+Message-Id: <20061204112518.14395.5648.sendpatchset@localhost.localdomain>
+Date: Mon,  4 Dec 2006 12:22:09 +0100 (MET)
+Cc: Patrick McHardy <kaber@trash.net>, davem@davemloft.net
+Subject: NETFILTER: Fix iptables compat hook validation
+
+From: Dmitry Mishin <dim@openvz.org>
+
+In compat mode, matches and targets valid hooks checks always successful due
+to not initialized e->comefrom field yet. This patch separates this checks from
+translation code and moves them after mark_source_chains() call, where these
+marks are initialized.
+
+Signed-off-by: Dmitry Mishin <dim@openvz.org>
+Signed-off-by; Patrick McHardy <kaber@trash.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+commit 14f5487cb9bd34cd59360d2cac7dccac9b27e8ce
+tree fab7cabcdb7fe450ff47bf42918f845ff3da1b86
+parent 756c508367e95d6f963502e4feecb8c76aeee332
+author Dmitry Mishin <dim@openvz.org> Mon, 04 Dec 2006 12:19:35 +0100
+committer Patrick McHardy <kaber@trash.net> Mon, 04 Dec 2006 12:19:35 +0100
+
+ net/ipv4/netfilter/ip_tables.c |   78 ++++++++++++++++++++++++++---------------
+ 1 file changed, 51 insertions(+), 27 deletions(-)
+
+--- linux-2.6.19.orig/net/ipv4/netfilter/ip_tables.c
++++ linux-2.6.19/net/ipv4/netfilter/ip_tables.c
+@@ -1516,25 +1516,8 @@ static inline int compat_copy_match_from
+       void **dstptr, compat_uint_t *size, const char *name,
+       const struct ipt_ip *ip, unsigned int hookmask)
+ {
+-      struct ipt_entry_match *dm;
+-      struct ipt_match *match;
+-      int ret;
+-
+-      dm = (struct ipt_entry_match *)*dstptr;
+-      match = m->u.kernel.match;
+       xt_compat_match_from_user(m, dstptr, size);
+-
+-      ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm),
+-                           name, hookmask, ip->proto,
+-                           ip->invflags & IPT_INV_PROTO);
+-      if (!ret && m->u.kernel.match->checkentry
+-          && !m->u.kernel.match->checkentry(name, ip, match, dm->data,
+-                                            hookmask)) {
+-              duprintf("ip_tables: check failed for `%s'.\n",
+-                       m->u.kernel.match->name);
+-              ret = -EINVAL;
+-      }
+-      return ret;
++      return 0;
+ }
+ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
+@@ -1556,7 +1539,7 @@ static int compat_copy_entry_from_user(s
+       ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size,
+                       name, &de->ip, de->comefrom);
+       if (ret)
+-              goto err;
++              return ret;
+       de->target_offset = e->target_offset - (origsize - *size);
+       t = ipt_get_target(e);
+       target = t->u.kernel.target;
+@@ -1569,26 +1552,62 @@ static int compat_copy_entry_from_user(s
+               if ((unsigned char *)de - base < newinfo->underflow[h])
+                       newinfo->underflow[h] -= origsize - *size;
+       }
++      return ret;
++}
++
++static inline int compat_check_match(struct ipt_entry_match *m, const char *name,
++                              const struct ipt_ip *ip, unsigned int hookmask)
++{
++      struct ipt_match *match;
++      int ret;
+-      t = ipt_get_target(de);
++      match = m->u.kernel.match;
++      ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m),
++                           name, hookmask, ip->proto,
++                           ip->invflags & IPT_INV_PROTO);
++      if (!ret && m->u.kernel.match->checkentry
++          && !m->u.kernel.match->checkentry(name, ip, match, m->data,
++                                            hookmask)) {
++              duprintf("ip_tables: compat: check failed for `%s'.\n",
++                       m->u.kernel.match->name);
++              ret = -EINVAL;
++      }
++      return ret;
++}
++
++static inline int compat_check_target(struct ipt_entry *e, const char *name)
++{
++      struct ipt_entry_target *t;
++      struct ipt_target *target;
++      int ret;
++
++      t = ipt_get_target(e);
+       target = t->u.kernel.target;
+       ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t),
+                             name, e->comefrom, e->ip.proto,
+                             e->ip.invflags & IPT_INV_PROTO);
+-      if (ret)
+-              goto err;
+-
+-      if (t->u.kernel.target->checkentry
+-                 && !t->u.kernel.target->checkentry(name, de, target,
+-                                                    t->data, de->comefrom)) {
++      if (!ret && t->u.kernel.target->checkentry
++                 && !t->u.kernel.target->checkentry(name, e, target,
++                                                    t->data, e->comefrom)) {
+               duprintf("ip_tables: compat: check failed for `%s'.\n",
+                        t->u.kernel.target->name);
+               ret = -EINVAL;
+       }
+-err:
+       return ret;
+ }
++static inline int compat_check_entry(struct ipt_entry *e, const char *name)
++{
++      int ret;
++
++      ret = IPT_MATCH_ITERATE(e, compat_check_match, name, &e->ip,
++                                                              e->comefrom);
++      if (ret)
++              return ret;
++
++      return compat_check_target(e, name);
++}
++
+ static int
+ translate_compat_table(const char *name,
+               unsigned int valid_hooks,
+@@ -1677,6 +1696,11 @@ translate_compat_table(const char *name,
+       if (!mark_source_chains(newinfo, valid_hooks, entry1))
+               goto free_newinfo;
++      ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
++                                                                      name);
++      if (ret)
++              goto free_newinfo;
++
+       /* And one copy for every other CPU */
+       for_each_possible_cpu(i)
+               if (newinfo->entries[i] && newinfo->entries[i] != entry1)
diff --git a/queue-2.6.19/pkt_sched-act_gact-division-by-zero.patch b/queue-2.6.19/pkt_sched-act_gact-division-by-zero.patch
new file mode 100644 (file)
index 0000000..f7b9c75
--- /dev/null
@@ -0,0 +1,39 @@
+From stable-bounces@linux.kernel.org  Fri Dec  1 20:41:40 2006
+Date: Fri, 01 Dec 2006 20:36:44 -0800 (PST)
+Message-Id: <20061201.203644.26925555.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: PKT_SCHED act_gact: division by zero
+
+Not returning -EINVAL, because someone might want to use the value
+zero in some future gact_prob algorithm?
+
+Signed-off-by: Kim Nordlund <kim.nordlund@nokia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+---
+ net/sched/act_gact.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- linux-2.6.19.orig/net/sched/act_gact.c
++++ linux-2.6.19/net/sched/act_gact.c
+@@ -48,14 +48,14 @@ static struct tcf_hashinfo gact_hash_inf
+ #ifdef CONFIG_GACT_PROB
+ static int gact_net_rand(struct tcf_gact *gact)
+ {
+-      if (net_random() % gact->tcfg_pval)
++      if (!gact->tcfg_pval || net_random() % gact->tcfg_pval)
+               return gact->tcf_action;
+       return gact->tcfg_paction;
+ }
+ static int gact_determ(struct tcf_gact *gact)
+ {
+-      if (gact->tcf_bstats.packets % gact->tcfg_pval)
++      if (!gact->tcfg_pval || gact->tcf_bstats.packets % gact->tcfg_pval)
+               return gact->tcf_action;
+       return gact->tcfg_paction;
+ }
index c4b93c4e79a43010bc582d8c605cd93efb8e05d6..4dbc2b0500ad4054fe26f727c2f6dc1d28210ca0 100644 (file)
@@ -7,3 +7,10 @@ ebtables-prevent-wraparounds-in-checks-for-entry-components-sizes.patch
 net_sched-policer-restore-compatibility-with-old-iproute-binaries.patch
 cryptoloop-select-crypto_cbc.patch
 revert-acpi-sci-interrupt-source-override.patch
+pkt_sched-act_gact-division-by-zero.patch
+sunhme-fix-for-sunhme-failures-on-x86.patch
+netfilter-fix-ip-ip6-arp-_tables-hook-validation.patch
+netfilter-fix-iptables-compat-hook-validation.patch
+netfilter-bridge-netfilter-deal-with-martians-correctly.patch
+softmac-fix-unbalanced-mutex_lock-unlock-in-ieee80211softmac_wx_set_mlme.patch
+ib-ucm-fix-deadlock-in-cleanup.patch
diff --git a/queue-2.6.19/softmac-fix-unbalanced-mutex_lock-unlock-in-ieee80211softmac_wx_set_mlme.patch b/queue-2.6.19/softmac-fix-unbalanced-mutex_lock-unlock-in-ieee80211softmac_wx_set_mlme.patch
new file mode 100644 (file)
index 0000000..14e2863
--- /dev/null
@@ -0,0 +1,40 @@
+From Larry.Finger@lwfinger.net  Sun Dec  3 08:45:48 2006
+Date: Sun, 03 Dec 2006 10:40:01 -0600
+From: Larry Finger <Larry.Finger@lwfinger.net>
+To: John Linville <linville@tuxdriver.com>, chrisw@sous-sol.org, stable@kernel.org
+Cc: maxime@tralhalla.org, Michael Buesch <mb@bu3sch.de>, Stefano Brivio <st3@riseup.net>
+Subject: [PATCH] softmac: fix unbalanced mutex_lock/unlock in ieee80211softmac_wx_set_mlme
+Message-ID: <4572FDE1.mail33M13NDAZ@lwfinger.net>
+
+From: Maxime Austruy <maxime@tralhalla.org>
+
+Routine ieee80211softmac_wx_set_mlme has one return that fails
+to release a mutex acquired at entry.
+
+Signed-off-by: Maxime Austruy <maxime@tralhalla.org>
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+John and Chris,
+
+This error was introduced in the 2.6.19-rxX series and must be applied
+to 2.6.19-stable and wireless-2.6.
+
+Larry
+
+ net/ieee80211/softmac/ieee80211softmac_wx.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- linux-2.6.19.orig/net/ieee80211/softmac/ieee80211softmac_wx.c
++++ linux-2.6.19/net/ieee80211/softmac/ieee80211softmac_wx.c
+@@ -495,7 +495,8 @@ ieee80211softmac_wx_set_mlme(struct net_
+                       printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n");
+                       goto out;
+               }
+-              return ieee80211softmac_deauth_req(mac, net, reason);
++              err =  ieee80211softmac_deauth_req(mac, net, reason);
++              goto out;
+       case IW_MLME_DISASSOC:
+               ieee80211softmac_send_disassoc_req(mac, reason);
+               mac->associnfo.associated = 0;
diff --git a/queue-2.6.19/sunhme-fix-for-sunhme-failures-on-x86.patch b/queue-2.6.19/sunhme-fix-for-sunhme-failures-on-x86.patch
new file mode 100644 (file)
index 0000000..7a031a7
--- /dev/null
@@ -0,0 +1,40 @@
+From stable-bounces@linux.kernel.org  Sun Dec  3 19:41:54 2006
+Date: Sun, 03 Dec 2006 19:36:32 -0800 (PST)
+Message-Id: <20061203.193632.41634212.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Subject: SUNHME: Fix for sunhme failures on x86
+
+From: Jurij Smakov <jurij@wooyd.org>
+
+The following patch fixes the failure of sunhme drivers on x86 hosts
+due to missing pci_enable_device() and pci_set_master() calls, lost
+during code refactoring. It has been filed as bugzilla bug #7502 [0]
+and Debian bug #397460 [1].
+
+[0] http://bugzilla.kernel.org/show_bug.cgi?id=7502
+[1] http://bugs.debian.org/397460
+
+Signed-off-by: Jurij Smakov <jurij@wooyd.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+---
+ drivers/net/sunhme.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- linux-2.6.19.orig/drivers/net/sunhme.c
++++ linux-2.6.19/drivers/net/sunhme.c
+@@ -3012,6 +3012,11 @@ static int __devinit happy_meal_pci_prob
+ #endif
+       err = -ENODEV;
++
++      if (pci_enable_device(pdev))
++              goto err_out;
++      pci_set_master(pdev);
++
+       if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) {
+               qp = quattro_pci_find(pdev);
+               if (qp == NULL)