From: Greg Kroah-Hartman Date: Mon, 19 Nov 2007 17:35:57 +0000 (-0800) Subject: some 2.6.22 networking fixes X-Git-Tag: v2.6.22.14~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1874cb395bab51d494286fc5a79fd304ffe3beca;p=thirdparty%2Fkernel%2Fstable-queue.git some 2.6.22 networking fixes --- diff --git a/queue-2.6.22/fix-crypto_alloc_comp-error-checking.patch b/queue-2.6.22/fix-crypto_alloc_comp-error-checking.patch new file mode 100644 index 00000000000..6ed7a3b33d0 --- /dev/null +++ b/queue-2.6.22/fix-crypto_alloc_comp-error-checking.patch @@ -0,0 +1,66 @@ +From stable-bounces@linux.kernel.org Tue Nov 13 02:48:46 2007 +From: Herbert Xu +Date: Tue, 13 Nov 2007 02:48:28 -0800 (PST) +Subject: Fix crypto_alloc_comp() error checking. +To: stable@kernel.org +Cc: bunk@kernel.org +Message-ID: <20071113.024828.260506088.davem@davemloft.net> + +From: Herbert Xu + +[IPSEC]: Fix crypto_alloc_comp error checking + +[ Upstream commit: 4999f3621f4da622e77931b3d33ada6c7083c705 ] + +The function crypto_alloc_comp returns an errno instead of NULL +to indicate error. So it needs to be tested with IS_ERR. + +This is based on a patch by Vicenç Beltran Querol. + +Signed-off-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/ipcomp.c | 3 ++- + net/ipv6/ipcomp6.c | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- a/net/ipv4/ipcomp.c ++++ b/net/ipv4/ipcomp.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -355,7 +356,7 @@ static struct crypto_comp **ipcomp_alloc + for_each_possible_cpu(cpu) { + struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0, + CRYPTO_ALG_ASYNC); +- if (!tfm) ++ if (IS_ERR(tfm)) + goto error; + *per_cpu_ptr(tfms, cpu) = tfm; + } +--- a/net/ipv6/ipcomp6.c ++++ b/net/ipv6/ipcomp6.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -366,7 +367,7 @@ static struct crypto_comp **ipcomp6_allo + for_each_possible_cpu(cpu) { + struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0, + CRYPTO_ALG_ASYNC); +- if (!tfm) ++ if (IS_ERR(tfm)) + goto error; + *per_cpu_ptr(tfms, cpu) = tfm; + } diff --git a/queue-2.6.22/fix-endianness-bug-in-u32-classifier.patch b/queue-2.6.22/fix-endianness-bug-in-u32-classifier.patch new file mode 100644 index 00000000000..049bc1b0d73 --- /dev/null +++ b/queue-2.6.22/fix-endianness-bug-in-u32-classifier.patch @@ -0,0 +1,84 @@ +From stable-bounces@linux.kernel.org Tue Nov 13 00:10:11 2007 +From: Radu Rendec +Date: Tue, 13 Nov 2007 00:09:56 -0800 (PST) +Subject: Fix endianness bug in U32 classifier. +To: stable@kernel.org +Cc: bunk@kernel.org +Message-ID: <20071113.000956.33032860.davem@davemloft.net> + +From: Radu Rendec + +changeset 543821c6f5dea5221426eaf1eac98b100249c7ac in mainline. + +[PKT_SCHED] CLS_U32: Fix endianness problem with u32 classifier hash masks. + +While trying to implement u32 hashes in my shaping machine I ran into +a possible bug in the u32 hash/bucket computing algorithm +(net/sched/cls_u32.c). + +The problem occurs only with hash masks that extend over the octet +boundary, on little endian machines (where htonl() actually does +something). + +Let's say that I would like to use 0x3fc0 as the hash mask. This means +8 contiguous "1" bits starting at b6. With such a mask, the expected +(and logical) behavior is to hash any address in, for instance, +192.168.0.0/26 in bucket 0, then any address in 192.168.0.64/26 in +bucket 1, then 192.168.0.128/26 in bucket 2 and so on. + +This is exactly what would happen on a big endian machine, but on +little endian machines, what would actually happen with current +implementation is 0x3fc0 being reversed (into 0xc03f0000) by htonl() +in the userspace tool and then applied to 192.168.x.x in the u32 +classifier. When shifting right by 16 bits (rank of first "1" bit in +the reversed mask) and applying the divisor mask (0xff for divisor +256), what would actually remain is 0x3f applied on the "168" octet of +the address. + +One could say is this can be easily worked around by taking endianness +into account in userspace and supplying an appropriate mask (0xfc03) +that would be turned into contiguous "1" bits when reversed +(0x03fc0000). But the actual problem is the network address (inside +the packet) not being converted to host order, but used as a +host-order value when computing the bucket. + +Let's say the network address is written as n31 n30 ... n0, with n0 +being the least significant bit. When used directly (without any +conversion) on a little endian machine, it becomes n7 ... n0 n8 ..n15 +etc in the machine's registers. Thus bits n7 and n8 would no longer be +adjacent and 192.168.64.0/26 and 192.168.128.0/26 would no longer be +consecutive. + +The fix is to apply ntohl() on the hmask before computing fshift, +and in u32_hash_fold() convert the packet data to host order before +shifting down by fshift. + +With helpful feedback from Jamal Hadi Salim and Jarek Poplawski. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/sched/cls_u32.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/sched/cls_u32.c ++++ b/net/sched/cls_u32.c +@@ -107,7 +107,7 @@ static struct tc_u_common *u32_list; + + static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel, u8 fshift) + { +- unsigned h = (key & sel->hmask)>>fshift; ++ unsigned h = ntohl(key & sel->hmask)>>fshift; + + return h; + } +@@ -631,7 +631,7 @@ static int u32_change(struct tcf_proto * + n->handle = handle; + { + u8 i = 0; +- u32 mask = s->hmask; ++ u32 mask = ntohl(s->hmask); + if (mask) { + while (!(mask & 1)) { + i++; diff --git a/queue-2.6.22/fix-error-returns-in-sys_socketpair.patch b/queue-2.6.22/fix-error-returns-in-sys_socketpair.patch new file mode 100644 index 00000000000..d31a5c5cfd2 --- /dev/null +++ b/queue-2.6.22/fix-error-returns-in-sys_socketpair.patch @@ -0,0 +1,46 @@ +From stable-bounces@linux.kernel.org Tue Nov 13 00:03:31 2007 +From: David Miller +Date: Tue, 13 Nov 2007 00:02:56 -0800 (PST) +Subject: Fix error returns in sys_socketpair() +To: stable@kernel.org +Cc: bunk@kernel.org +Message-ID: <20071113.000256.110812500.davem@davemloft.net> + +From: David Miller + +patch bf3c23d171e35e6e168074a1514b0acd59cfd81a in mainline. + +[NET]: Fix error reporting in sys_socketpair(). + +If either of the two sock_alloc_fd() calls fail, we +forget to update 'err' and thus we'll erroneously +return zero in these cases. + +Based upon a report and patch from Rich Paul, and +commentary from Chuck Ebbert. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/socket.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/net/socket.c ++++ b/net/socket.c +@@ -1246,11 +1246,14 @@ asmlinkage long sys_socketpair(int famil + goto out_release_both; + + fd1 = sock_alloc_fd(&newfile1); +- if (unlikely(fd1 < 0)) ++ if (unlikely(fd1 < 0)) { ++ err = fd1; + goto out_release_both; ++ } + + fd2 = sock_alloc_fd(&newfile2); + if (unlikely(fd2 < 0)) { ++ err = fd2; + put_filp(newfile1); + put_unused_fd(fd1); + goto out_release_both; diff --git a/queue-2.6.22/fix-netlink-timeouts.patch b/queue-2.6.22/fix-netlink-timeouts.patch new file mode 100644 index 00000000000..ddbc719c395 --- /dev/null +++ b/queue-2.6.22/fix-netlink-timeouts.patch @@ -0,0 +1,112 @@ +From stable-bounces@linux.kernel.org Tue Nov 13 03:31:15 2007 +From: Patrick McHardy +Date: Tue, 13 Nov 2007 03:03:00 -0800 (PST) +Subject: Fix netlink timeouts. +To: stable@kernel.org +Cc: bunk@kernel.org +Message-ID: <20071113.030300.51440049.davem@davemloft.net> + +From: Patrick McHardy + +[NETLINK]: Fix unicast timeouts + +[ Upstream commit: c3d8d1e30cace31fed6186a4b8c6b1401836d89c ] + +Commit ed6dcf4a in the history.git tree broke netlink_unicast timeouts +by moving the schedule_timeout() call to a new function that doesn't +propagate the remaining timeout back to the caller. This means on each +retry we start with the full timeout again. + +ipc/mqueue.c seems to actually want to wait indefinitely so this +behaviour is retained. + +Signed-off-by: Patrick McHardy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/netlink.h | 2 +- + ipc/mqueue.c | 6 ++++-- + net/netlink/af_netlink.c | 10 +++++----- + 3 files changed, 10 insertions(+), 8 deletions(-) + +--- a/include/linux/netlink.h ++++ b/include/linux/netlink.h +@@ -173,7 +173,7 @@ extern int netlink_unregister_notifier(s + /* finegrained unicast helpers: */ + struct sock *netlink_getsockbyfilp(struct file *filp); + int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, +- long timeo, struct sock *ssk); ++ long *timeo, struct sock *ssk); + void netlink_detachskb(struct sock *sk, struct sk_buff *skb); + int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol); + +--- a/ipc/mqueue.c ++++ b/ipc/mqueue.c +@@ -1014,6 +1014,8 @@ asmlinkage long sys_mq_notify(mqd_t mqde + return -EINVAL; + } + if (notification.sigev_notify == SIGEV_THREAD) { ++ long timeo; ++ + /* create the notify skb */ + nc = alloc_skb(NOTIFY_COOKIE_LEN, GFP_KERNEL); + ret = -ENOMEM; +@@ -1042,8 +1044,8 @@ retry: + goto out; + } + +- ret = netlink_attachskb(sock, nc, 0, +- MAX_SCHEDULE_TIMEOUT, NULL); ++ timeo = MAX_SCHEDULE_TIMEOUT; ++ ret = netlink_attachskb(sock, nc, 0, &timeo, NULL); + if (ret == 1) + goto retry; + if (ret) { +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -732,7 +732,7 @@ struct sock *netlink_getsockbyfilp(struc + * 1: repeat lookup - reference dropped while waiting for socket memory. + */ + int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, +- long timeo, struct sock *ssk) ++ long *timeo, struct sock *ssk) + { + struct netlink_sock *nlk; + +@@ -741,7 +741,7 @@ int netlink_attachskb(struct sock *sk, s + if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || + test_bit(0, &nlk->state)) { + DECLARE_WAITQUEUE(wait, current); +- if (!timeo) { ++ if (!*timeo) { + if (!ssk || nlk_sk(ssk)->pid == 0) + netlink_overrun(sk); + sock_put(sk); +@@ -755,7 +755,7 @@ int netlink_attachskb(struct sock *sk, s + if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || + test_bit(0, &nlk->state)) && + !sock_flag(sk, SOCK_DEAD)) +- timeo = schedule_timeout(timeo); ++ *timeo = schedule_timeout(*timeo); + + __set_current_state(TASK_RUNNING); + remove_wait_queue(&nlk->wait, &wait); +@@ -763,7 +763,7 @@ int netlink_attachskb(struct sock *sk, s + + if (signal_pending(current)) { + kfree_skb(skb); +- return sock_intr_errno(timeo); ++ return sock_intr_errno(*timeo); + } + return 1; + } +@@ -827,7 +827,7 @@ retry: + kfree_skb(skb); + return PTR_ERR(sk); + } +- err = netlink_attachskb(sk, skb, nonblock, timeo, ssk); ++ err = netlink_attachskb(sk, skb, nonblock, &timeo, ssk); + if (err == 1) + goto retry; + if (err) diff --git a/queue-2.6.22/fix-teql-oops.patch b/queue-2.6.22/fix-teql-oops.patch new file mode 100644 index 00000000000..1347199df15 --- /dev/null +++ b/queue-2.6.22/fix-teql-oops.patch @@ -0,0 +1,39 @@ +From stable-bounces@linux.kernel.org Tue Nov 13 00:08:07 2007 +From: Evgeniy Polyakov +Date: Tue, 13 Nov 2007 00:07:45 -0800 (PST) +Subject: Fix TEQL oops. +To: stable@kernel.org +Cc: bunk@kernel.org +Message-ID: <20071113.000745.02473542.davem@davemloft.net> + +From: Evgeniy Polyakov + +[PKT_SCHED]: Fix OOPS when removing devices from a teql queuing discipline + +[ Upstream commit: 4f9f8311a08c0d95c70261264a2b47f2ae99683a ] + +tecl_reset() is called from deactivate and qdisc is set to noop already, +but subsequent teql_xmit does not know about it and dereference private +data as teql qdisc and thus oopses. +not catch it first :) + +Signed-off-by: Evgeniy Polyakov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/sched/sch_teql.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/sched/sch_teql.c ++++ b/net/sched/sch_teql.c +@@ -263,6 +263,9 @@ __teql_resolve(struct sk_buff *skb, stru + static __inline__ int + teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev) + { ++ if (dev->qdisc == &noop_qdisc) ++ return -ENODEV; ++ + if (dev->hard_header == NULL || + skb->dst == NULL || + skb->dst->neighbour == NULL) diff --git a/queue-2.6.22/fix-the-softlockup-watchdog-to-actually-work.patch b/queue-2.6.22/fix-the-softlockup-watchdog-to-actually-work.patch new file mode 100644 index 00000000000..fd1f26c2fef --- /dev/null +++ b/queue-2.6.22/fix-the-softlockup-watchdog-to-actually-work.patch @@ -0,0 +1,60 @@ +From stable-bounces@linux.kernel.org Tue Oct 16 23:29:17 2007 +From: Ingo Molnar +Date: Tue, 16 Oct 2007 23:18:38 -0700 +Subject: fix the softlockup watchdog to actually work +To: torvalds@linux-foundation.org +Cc: akpm@linux-foundation.org, mingo@elte.hu, jeremy@goop.org, stable@kernel.org +Message-ID: <200710170618.l9H6IcbE005545@imap1.linux-foundation.org> + + +From: Ingo Molnar + +patch a115d5caca1a2905ba7a32b408a6042b20179aaa in mainline. + +this Xen related commit: + + commit 966812dc98e6a7fcdf759cbfa0efab77500a8868 + Author: Jeremy Fitzhardinge + Date: Tue May 8 00:28:02 2007 -0700 + + Ignore stolen time in the softlockup watchdog + +broke the softlockup watchdog to never report any lockups. (!) + +print_timestamp defaults to 0, this makes the following condition +always true: + + if (print_timestamp < (touch_timestamp + 1) || + +and we'll in essence never report soft lockups. + +apparently the functionality of the soft lockup watchdog was never +actually tested with that patch applied ... + +Signed-off-by: Ingo Molnar +Cc: Jeremy Fitzhardinge +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/softlockup.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/kernel/softlockup.c ++++ b/kernel/softlockup.c +@@ -79,10 +79,11 @@ void softlockup_tick(void) + print_timestamp = per_cpu(print_timestamp, this_cpu); + + /* report at most once a second */ +- if (print_timestamp < (touch_timestamp + 1) || +- did_panic || +- !per_cpu(watchdog_task, this_cpu)) ++ if ((print_timestamp >= touch_timestamp && ++ print_timestamp < (touch_timestamp + 1)) || ++ did_panic || !per_cpu(watchdog_task, this_cpu)) { + return; ++ } + + /* do not print during early bootup: */ + if (unlikely(system_state != SYSTEM_RUNNING)) { diff --git a/queue-2.6.22/netfilter-nf_conntrack_tcp-fix-connection-reopening.patch b/queue-2.6.22/netfilter-nf_conntrack_tcp-fix-connection-reopening.patch new file mode 100644 index 00000000000..0a35b956b59 --- /dev/null +++ b/queue-2.6.22/netfilter-nf_conntrack_tcp-fix-connection-reopening.patch @@ -0,0 +1,101 @@ +From stable-bounces@linux.kernel.org Mon Nov 5 03:38:25 2007 +From: Jozsef Kadlecsik +Date: Mon, 05 Nov 2007 12:37:55 +0100 +Subject: NETFILTER: nf_conntrack_tcp: fix connection reopening +To: stable@kernel.org +Cc: Netfilter Development Mailinglist , "David S. Miller" , Krzysztof Piotr Oledzki , Jozsef Kadlecsik +Message-ID: <472F0093.6040508@trash.net> + +From: Jozsef Kadlecsik + +Upstream commits: 17311393 + bc34b841 merged together. Merge done by +Patrick McHardy + +[NETFILTER]: nf_conntrack_tcp: fix connection reopening + +With your description I could reproduce the bug and actually you were +completely right: the code above is incorrect. Somehow I was able to +misread RFC1122 and mixed the roles :-(: + + When a connection is >>closed actively<<, it MUST linger in + TIME-WAIT state for a time 2xMSL (Maximum Segment Lifetime). + However, it MAY >>accept<< a new SYN from the remote TCP to + reopen the connection directly from TIME-WAIT state, if it: + [...] + +The fix is as follows: if the receiver initiated an active close, then the +sender may reopen the connection - otherwise try to figure out if we hold +a dead connection. + +Signed-off-by: Jozsef Kadlecsik +Tested-by: Krzysztof Piotr Oledzki +Signed-off-by: Patrick McHardy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + + +--- + net/netfilter/nf_conntrack_proto_tcp.c | 38 ++++++++++++++------------------- + 1 file changed, 17 insertions(+), 21 deletions(-) + +--- a/net/netfilter/nf_conntrack_proto_tcp.c ++++ b/net/netfilter/nf_conntrack_proto_tcp.c +@@ -839,6 +839,22 @@ static int tcp_packet(struct nf_conn *co + new_state = tcp_conntracks[dir][index][old_state]; + + switch (new_state) { ++ case TCP_CONNTRACK_SYN_SENT: ++ if (old_state < TCP_CONNTRACK_TIME_WAIT) ++ break; ++ if ((conntrack->proto.tcp.seen[!dir].flags & ++ IP_CT_TCP_FLAG_CLOSE_INIT) ++ || (conntrack->proto.tcp.last_dir == dir ++ && conntrack->proto.tcp.last_index == TCP_RST_SET)) { ++ /* Attempt to reopen a closed/aborted connection. ++ * Delete this connection and look up again. */ ++ write_unlock_bh(&tcp_lock); ++ if (del_timer(&conntrack->timeout)) ++ conntrack->timeout.function((unsigned long) ++ conntrack); ++ return -NF_REPEAT; ++ } ++ /* Fall through */ + case TCP_CONNTRACK_IGNORE: + /* Ignored packets: + * +@@ -888,27 +904,6 @@ static int tcp_packet(struct nf_conn *co + nf_log_packet(pf, 0, skb, NULL, NULL, NULL, + "nf_ct_tcp: invalid state "); + return -NF_ACCEPT; +- case TCP_CONNTRACK_SYN_SENT: +- if (old_state < TCP_CONNTRACK_TIME_WAIT) +- break; +- if ((conntrack->proto.tcp.seen[dir].flags & +- IP_CT_TCP_FLAG_CLOSE_INIT) +- || after(ntohl(th->seq), +- conntrack->proto.tcp.seen[dir].td_end)) { +- /* Attempt to reopen a closed connection. +- * Delete this connection and look up again. */ +- write_unlock_bh(&tcp_lock); +- if (del_timer(&conntrack->timeout)) +- conntrack->timeout.function((unsigned long) +- conntrack); +- return -NF_REPEAT; +- } else { +- write_unlock_bh(&tcp_lock); +- if (LOG_INVALID(IPPROTO_TCP)) +- nf_log_packet(pf, 0, skb, NULL, NULL, +- NULL, "nf_ct_tcp: invalid SYN"); +- return -NF_ACCEPT; +- } + case TCP_CONNTRACK_CLOSE: + if (index == TCP_RST_SET + && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) +@@ -941,6 +936,7 @@ static int tcp_packet(struct nf_conn *co + in_window: + /* From now on we have got in-window packets */ + conntrack->proto.tcp.last_index = index; ++ conntrack->proto.tcp.last_dir = dir; + + DEBUGP("tcp_conntracks: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu " + "syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n", diff --git a/queue-2.6.22/series b/queue-2.6.22/series index 1674a709d67..ac4c9543ac0 100644 --- a/queue-2.6.22/series +++ b/queue-2.6.22/series @@ -13,3 +13,10 @@ i4l-fix-random-freezes-with-avm-b1-drivers.patch x86-fix-tsc-clock-source-calibration-error.patch writeback-don-t-propagate-aop_writepage_activate.patch ide-fix-serverworks.c-udma-regression.patch +netfilter-nf_conntrack_tcp-fix-connection-reopening.patch +fix-the-softlockup-watchdog-to-actually-work.patch +fix-teql-oops.patch +fix-netlink-timeouts.patch +fix-error-returns-in-sys_socketpair.patch +fix-endianness-bug-in-u32-classifier.patch +fix-crypto_alloc_comp-error-checking.patch