From: Chris Wright Date: Mon, 4 Dec 2006 23:28:36 +0000 (-0800) Subject: -stable patches from the weekend, dups for 18/19: X-Git-Tag: v2.6.19.1~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=37b41a212c4213028e9c185eeb2ba19c8283b5cd;p=thirdparty%2Fkernel%2Fstable-queue.git -stable patches from the weekend, dups for 18/19: 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 --- 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 index 00000000000..64a720315d6 --- /dev/null +++ b/queue-2.6.18/netfilter-ip_tables-revision-support-for-compat-code.patch @@ -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 +Cc: bunk@stusta.de +Subject: NETFILTER: ip_tables: revision support for compat code + +From: Patrick McHardy + +Signed-off-by: Patrick McHardy +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- +commit 79030ed07de673e8451a03aecb9ada9f4d75d491 +tree 4ba8bd843c8bc95db0ea6877880b73d06da620e5 +parent bec71b162747708d4b45b0cd399b484f52f2901a +author Patrick McHardy Wed, 20 Sep 2006 12:05:08 -0700 +committer David S. Miller 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 index 00000000000..475061417f2 --- /dev/null +++ b/queue-2.6.18/pkt_sched-act_gact-division-by-zero.patch @@ -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 +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 +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + + +--- + 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; + } diff --git a/queue-2.6.18/series b/queue-2.6.18/series index a263fbf59ee..c1331e74b90 100644 --- a/queue-2.6.18/series +++ b/queue-2.6.18/series @@ -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 index 00000000000..5d25e4d53de --- /dev/null +++ b/queue-2.6.18/sunhme-fix-for-sunhme-failures-on-x86.patch @@ -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 +Subject: SUNHME: Fix for sunhme failures on x86 + +From: Jurij Smakov + +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 +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + +--- + 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 index 00000000000..431d6decb2b --- /dev/null +++ b/queue-2.6.19/ib-ucm-fix-deadlock-in-cleanup.patch @@ -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" +To: stable@kernel.org, Roland Dreier , Sean Hefty +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 +Signed-off-by: Roland Dreier +Acked-by: Sean Hefty +Signed-off-by: Chris Wright + +--- + +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); + } diff --git a/queue-2.6.19/ndisc-calculate-packet-length-correctly-for-allocation.patch b/queue-2.6.19/ndisc-calculate-packet-length-correctly-for-allocation.patch index 8c13314a260..c0ceaa32f78 100644 --- a/queue-2.6.19/ndisc-calculate-packet-length-correctly-for-allocation.patch +++ b/queue-2.6.19/ndisc-calculate-packet-length-correctly-for-allocation.patch @@ -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 +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 Signed-off-by: Chris Wright --- - net/ipv6/ndisc.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) +commit 6e38433357e2381bb278a418fb7e2fd201475101 +Author: David S. Miller +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 index 00000000000..2175bbfffb7 --- /dev/null +++ b/queue-2.6.19/netfilter-bridge-netfilter-deal-with-martians-correctly.patch @@ -0,0 +1,124 @@ +From stable-bounces@linux.kernel.org Mon Dec 4 03:27:33 2006 +From: Patrick McHardy +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 , davem@davemloft.net +Subject: NETFILTER: bridge netfilter: deal with martians correctly + +From: Bart De Schuymer + +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 for +reporting this problem. + +This is probably a candidate for the -stable release. + +Signed-off-by: Bart De Schuymer +Signed-off-by: Patrick McHardy +Signed-off-by: Chris Wright + +--- +commit bb01f827bae980efdecc33fbcdc1b90f1c355b3e +tree 432a8f2843b47ccac094efea35da6f19731ed834 +parent 14f5487cb9bd34cd59360d2cac7dccac9b27e8ce +author Bart De Schuymer Mon, 04 Dec 2006 12:19:46 +0100 +committer Patrick McHardy 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 + #include + #include ++#include + + #include + #include +@@ -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 index 00000000000..114b0a30043 --- /dev/null +++ b/queue-2.6.19/netfilter-fix-ip-ip6-arp-_tables-hook-validation.patch @@ -0,0 +1,371 @@ +From stable-bounces@linux.kernel.org Mon Dec 4 03:27:25 2006 +From: Patrick McHardy +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 , davem@davemloft.net +Subject: NETFILTER: Fix {ip, ip6, arp}_tables hook validation + +From: Dmitry Mishin + +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 +Signed-off-by: Patrick McHardy +Signed-off-by: Chris Wright + +--- +commit 756c508367e95d6f963502e4feecb8c76aeee332 +tree 2be0ffb477e890a713eb48f3993a2f425baf5683 +parent 0215ffb08ce99e2bb59eca114a99499a4d06e704 +author Dmitry Mishin Mon, 04 Dec 2006 12:19:27 +0100 +committer Patrick McHardy 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 index 00000000000..b22bbc02a83 --- /dev/null +++ b/queue-2.6.19/netfilter-fix-iptables-compat-hook-validation.patch @@ -0,0 +1,150 @@ +From stable-bounces@linux.kernel.org Mon Dec 4 03:27:30 2006 +From: Patrick McHardy +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 , davem@davemloft.net +Subject: NETFILTER: Fix iptables compat hook validation + +From: Dmitry Mishin + +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 +Signed-off-by; Patrick McHardy +Signed-off-by: Chris Wright + +--- +commit 14f5487cb9bd34cd59360d2cac7dccac9b27e8ce +tree fab7cabcdb7fe450ff47bf42918f845ff3da1b86 +parent 756c508367e95d6f963502e4feecb8c76aeee332 +author Dmitry Mishin Mon, 04 Dec 2006 12:19:35 +0100 +committer Patrick McHardy 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 index 00000000000..f7b9c75697d --- /dev/null +++ b/queue-2.6.19/pkt_sched-act_gact-division-by-zero.patch @@ -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 +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 +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + +--- + 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; + } diff --git a/queue-2.6.19/series b/queue-2.6.19/series index c4b93c4e79a..4dbc2b0500a 100644 --- a/queue-2.6.19/series +++ b/queue-2.6.19/series @@ -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 index 00000000000..14e2863b107 --- /dev/null +++ b/queue-2.6.19/softmac-fix-unbalanced-mutex_lock-unlock-in-ieee80211softmac_wx_set_mlme.patch @@ -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 +To: John Linville , chrisw@sous-sol.org, stable@kernel.org +Cc: maxime@tralhalla.org, Michael Buesch , Stefano Brivio +Subject: [PATCH] softmac: fix unbalanced mutex_lock/unlock in ieee80211softmac_wx_set_mlme +Message-ID: <4572FDE1.mail33M13NDAZ@lwfinger.net> + +From: Maxime Austruy + +Routine ieee80211softmac_wx_set_mlme has one return that fails +to release a mutex acquired at entry. + +Signed-off-by: Maxime Austruy +Signed-off-by: Larry Finger +Signed-off-by: Chris Wright +--- + +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 index 00000000000..7a031a7f704 --- /dev/null +++ b/queue-2.6.19/sunhme-fix-for-sunhme-failures-on-x86.patch @@ -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 +Subject: SUNHME: Fix for sunhme failures on x86 + +From: Jurij Smakov + +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 +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + +--- + 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)