From: Greg Kroah-Hartman Date: Fri, 9 Oct 2009 23:32:24 +0000 (-0700) Subject: networking patches for .31 X-Git-Tag: v2.6.27.37~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0a470951e3c36a60b2d1bd6d8be61b0724eb292d;p=thirdparty%2Fkernel%2Fstable-queue.git networking patches for .31 --- diff --git a/review-2.6.31/appletalk-fix-skb-leak-when-ipddp-interface-is-not-loaded.patch b/review-2.6.31/appletalk-fix-skb-leak-when-ipddp-interface-is-not-loaded.patch new file mode 100644 index 00000000000..eee90c3acd5 --- /dev/null +++ b/review-2.6.31/appletalk-fix-skb-leak-when-ipddp-interface-is-not-loaded.patch @@ -0,0 +1,222 @@ +From 583a5cfb324d61e747243abaebba5f14c8bd25e0 Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +Date: Wed, 9 Sep 2009 11:40:12 -0300 +Subject: appletalk: Fix skb leak when ipddp interface is not loaded + +From: Arnaldo Carvalho de Melo + +[ Upstream commit ffcfb8db540ff879c2a85bf7e404954281443414 ] + +And also do a better job of returning proper NET_{RX,XMIT}_ values. + +Based on a patch by Mark Smith. + +This fixes CVE-2009-2903 + +Reported-by: Mark Smith +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/appletalk/ipddp.c | 3 -- + net/appletalk/aarp.c | 16 +++++++---- + net/appletalk/ddp.c | 58 ++++++++++++++++++++++-------------------- + 3 files changed, 43 insertions(+), 34 deletions(-) + +--- a/drivers/net/appletalk/ipddp.c ++++ b/drivers/net/appletalk/ipddp.c +@@ -176,8 +176,7 @@ static int ipddp_xmit(struct sk_buff *sk + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + +- if(aarp_send_ddp(rt->dev, skb, &rt->at, NULL) < 0) +- dev_kfree_skb(skb); ++ aarp_send_ddp(rt->dev, skb, &rt->at, NULL); + + spin_unlock(&ipddp_route_lock); + +--- a/net/appletalk/aarp.c ++++ b/net/appletalk/aarp.c +@@ -599,7 +599,7 @@ int aarp_send_ddp(struct net_device *dev + + /* Non ELAP we cannot do. */ + if (dev->type != ARPHRD_ETHER) +- return -1; ++ goto free_it; + + skb->dev = dev; + skb->protocol = htons(ETH_P_ATALK); +@@ -634,7 +634,7 @@ int aarp_send_ddp(struct net_device *dev + if (!a) { + /* Whoops slipped... good job it's an unreliable protocol 8) */ + write_unlock_bh(&aarp_lock); +- return -1; ++ goto free_it; + } + + /* Set up the queue */ +@@ -663,15 +663,21 @@ out_unlock: + write_unlock_bh(&aarp_lock); + + /* Tell the ddp layer we have taken over for this frame. */ +- return 0; ++ goto sent; + + sendit: + if (skb->sk) + skb->priority = skb->sk->sk_priority; +- dev_queue_xmit(skb); ++ if (dev_queue_xmit(skb)) ++ goto drop; + sent: +- return 1; ++ return NET_XMIT_SUCCESS; ++free_it: ++ kfree_skb(skb); ++drop: ++ return NET_XMIT_DROP; + } ++EXPORT_SYMBOL(aarp_send_ddp); + + /* + * An entry in the aarp unresolved queue has become resolved. Send +--- a/net/appletalk/ddp.c ++++ b/net/appletalk/ddp.c +@@ -1270,8 +1270,10 @@ static int handle_ip_over_ddp(struct sk_ + struct net_device_stats *stats; + + /* This needs to be able to handle ipddp"N" devices */ +- if (!dev) +- return -ENODEV; ++ if (!dev) { ++ kfree_skb(skb); ++ return NET_RX_DROP; ++ } + + skb->protocol = htons(ETH_P_IP); + skb_pull(skb, 13); +@@ -1281,8 +1283,7 @@ static int handle_ip_over_ddp(struct sk_ + stats = netdev_priv(dev); + stats->rx_packets++; + stats->rx_bytes += skb->len + 13; +- netif_rx(skb); /* Send the SKB up to a higher place. */ +- return 0; ++ return netif_rx(skb); /* Send the SKB up to a higher place. */ + } + #else + /* make it easy for gcc to optimize this test out, i.e. kill the code */ +@@ -1290,9 +1291,8 @@ static int handle_ip_over_ddp(struct sk_ + #define handle_ip_over_ddp(skb) 0 + #endif + +-static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev, +- struct ddpehdr *ddp, __u16 len_hops, +- int origlen) ++static int atalk_route_packet(struct sk_buff *skb, struct net_device *dev, ++ struct ddpehdr *ddp, __u16 len_hops, int origlen) + { + struct atalk_route *rt; + struct atalk_addr ta; +@@ -1359,8 +1359,6 @@ static void atalk_route_packet(struct sk + /* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */ + struct sk_buff *nskb = skb_realloc_headroom(skb, 32); + kfree_skb(skb); +- if (!nskb) +- goto out; + skb = nskb; + } else + skb = skb_unshare(skb, GFP_ATOMIC); +@@ -1369,12 +1367,18 @@ static void atalk_route_packet(struct sk + * If the buffer didn't vanish into the lack of space bitbucket we can + * send it. + */ +- if (skb && aarp_send_ddp(rt->dev, skb, &ta, NULL) == -1) +- goto free_it; +-out: +- return; ++ if (skb == NULL) ++ goto drop; ++ ++ /* ++ * It is OK, NET_XMIT_SUCCESS == NET_RX_SUCCESS and ++ * NET_XMIT_DROP == NET_RX_DROP ++ */ ++ return aarp_send_ddp(rt->dev, skb, &ta, NULL); + free_it: + kfree_skb(skb); ++drop: ++ return NET_RX_DROP; + } + + /** +@@ -1404,7 +1408,7 @@ static int atalk_rcv(struct sk_buff *skb + + /* Don't mangle buffer if shared */ + if (!(skb = skb_share_check(skb, GFP_ATOMIC))) +- goto out; ++ goto drop; + + /* Size check and make sure header is contiguous */ + if (!pskb_may_pull(skb, sizeof(*ddp))) +@@ -1448,8 +1452,7 @@ static int atalk_rcv(struct sk_buff *skb + /* Not ours, so we route the packet via the correct + * AppleTalk iface + */ +- atalk_route_packet(skb, dev, ddp, len_hops, origlen); +- goto out; ++ return atalk_route_packet(skb, dev, ddp, len_hops, origlen); + } + + /* if IP over DDP is not selected this code will be optimized out */ +@@ -1472,11 +1475,12 @@ static int atalk_rcv(struct sk_buff *skb + + if (sock_queue_rcv_skb(sock, skb) < 0) + goto freeit; +-out: +- return 0; ++ ++ return NET_RX_SUCCESS; + freeit: + kfree_skb(skb); +- goto out; ++drop: ++ return NET_RX_DROP; + } + + /* +@@ -1652,10 +1656,10 @@ static int atalk_sendmsg(struct kiocb *i + if (skb2) { + loopback = 1; + SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk); +- if (aarp_send_ddp(dev, skb2, +- &usat->sat_addr, NULL) == -1) +- kfree_skb(skb2); +- /* else queued/sent above in the aarp queue */ ++ /* ++ * If it fails it is queued/sent above in the aarp queue ++ */ ++ aarp_send_ddp(dev, skb2, &usat->sat_addr, NULL); + } + } + +@@ -1685,9 +1689,10 @@ static int atalk_sendmsg(struct kiocb *i + usat = &gsat; + } + +- if (aarp_send_ddp(dev, skb, &usat->sat_addr, NULL) == -1) +- kfree_skb(skb); +- /* else queued/sent above in the aarp queue */ ++ /* ++ * If it fails it is queued/sent above in the aarp queue ++ */ ++ aarp_send_ddp(dev, skb, &usat->sat_addr, NULL); + } + SOCK_DEBUG(sk, "SK %p: Done write (%Zd).\n", sk, len); + +@@ -1865,7 +1870,6 @@ static struct packet_type ppptalk_packet + static unsigned char ddp_snap_id[] = { 0x08, 0x00, 0x07, 0x80, 0x9B }; + + /* Export symbols for use by drivers when AppleTalk is a module */ +-EXPORT_SYMBOL(aarp_send_ddp); + EXPORT_SYMBOL(atrtr_get_dev); + EXPORT_SYMBOL(atalk_find_dev_addr); + diff --git a/review-2.6.31/ax25-fix-possible-oops-in-ax25_make_new.patch b/review-2.6.31/ax25-fix-possible-oops-in-ax25_make_new.patch new file mode 100644 index 00000000000..2272e6cf708 --- /dev/null +++ b/review-2.6.31/ax25-fix-possible-oops-in-ax25_make_new.patch @@ -0,0 +1,40 @@ +From fc19457a1971fee7f7e2b7f2346a5f66cfa2867c Mon Sep 17 00:00:00 2001 +From: Jarek Poplawski +Date: Sun, 27 Sep 2009 10:57:02 +0000 +Subject: ax25: Fix possible oops in ax25_make_new + +From: Jarek Poplawski + +[ Upstream commit 8c185ab6185bf5e67766edb000ce428269364c86 ] + +In ax25_make_new, if kmemdup of digipeat returns an error, there would +be an oops in sk_free while calling sk_destruct, because sk_protinfo +is NULL at the moment; move sk->sk_destruct initialization after this. + +BTW of reported-by: Bernard Pidoux F6BVP + +Signed-off-by: Jarek Poplawski +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ax25/af_ax25.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ax25/af_ax25.c ++++ b/net/ax25/af_ax25.c +@@ -893,7 +893,6 @@ struct sock *ax25_make_new(struct sock * + + sock_init_data(NULL, sk); + +- sk->sk_destruct = ax25_free_sock; + sk->sk_type = osk->sk_type; + sk->sk_priority = osk->sk_priority; + sk->sk_protocol = osk->sk_protocol; +@@ -931,6 +930,7 @@ struct sock *ax25_make_new(struct sock * + } + + sk->sk_protinfo = ax25; ++ sk->sk_destruct = ax25_free_sock; + ax25->sk = sk; + + return sk; diff --git a/review-2.6.31/ax25-fix-siocax25getinfo-ioctl.patch b/review-2.6.31/ax25-fix-siocax25getinfo-ioctl.patch new file mode 100644 index 00000000000..ed5fc525bd8 --- /dev/null +++ b/review-2.6.31/ax25-fix-siocax25getinfo-ioctl.patch @@ -0,0 +1,34 @@ +From 87ce8442b838ff63c60766e1ef93eb86c026539f Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sun, 20 Sep 2009 06:32:55 +0000 +Subject: ax25: Fix SIOCAX25GETINFO ioctl + +From: Eric Dumazet + +[ Upstream commit 407fc5cf019fc5cb990458a2e38d2c0a27b3cb30 ] + +rcv_q & snd_q initializations were reversed in commit +31e6d363abcd0d05766c82f1a9c905a4c974a199 +(net: correct off-by-one write allocations reports) + +Signed-off-by: Jan Rafaj +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ax25/af_ax25.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ax25/af_ax25.c ++++ b/net/ax25/af_ax25.c +@@ -1781,8 +1781,8 @@ static int ax25_ioctl(struct socket *soc + ax25_info.idletimer = ax25_display_timer(&ax25->idletimer) / (60 * HZ); + ax25_info.n2count = ax25->n2count; + ax25_info.state = ax25->state; +- ax25_info.rcv_q = sk_wmem_alloc_get(sk); +- ax25_info.snd_q = sk_rmem_alloc_get(sk); ++ ax25_info.rcv_q = sk_rmem_alloc_get(sk); ++ ax25_info.snd_q = sk_wmem_alloc_get(sk); + ax25_info.vs = ax25->vs; + ax25_info.vr = ax25->vr; + ax25_info.va = ax25->va; diff --git a/review-2.6.31/net-fix-sock_wfree-race.patch b/review-2.6.31/net-fix-sock_wfree-race.patch new file mode 100644 index 00000000000..c0920f65c3e --- /dev/null +++ b/review-2.6.31/net-fix-sock_wfree-race.patch @@ -0,0 +1,57 @@ +From de8dee3c92f58c30295c6d654805698b5bf42df3 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 24 Sep 2009 10:49:24 +0000 +Subject: net: Fix sock_wfree() race + +From: Eric Dumazet + +[ Upstream commit d99927f4d93f36553699573b279e0ff98ad7dea6 ] + +Commit 2b85a34e911bf483c27cfdd124aeb1605145dc80 +(net: No more expensive sock_hold()/sock_put() on each tx) +opens a window in sock_wfree() where another cpu +might free the socket we are working on. + +A fix is to call sk->sk_write_space(sk) while still +holding a reference on sk. + +Reported-by: Jike Song +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/sock.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1218,17 +1218,22 @@ void __init sk_init(void) + void sock_wfree(struct sk_buff *skb) + { + struct sock *sk = skb->sk; +- int res; ++ unsigned int len = skb->truesize; + +- /* In case it might be waiting for more memory. */ +- res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc); +- if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) ++ if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) { ++ /* ++ * Keep a reference on sk_wmem_alloc, this will be released ++ * after sk_write_space() call ++ */ ++ atomic_sub(len - 1, &sk->sk_wmem_alloc); + sk->sk_write_space(sk); ++ len = 1; ++ } + /* +- * if sk_wmem_alloc reached 0, we are last user and should +- * free this sock, as sk_free() call could not do it. ++ * if sk_wmem_alloc reaches 0, we must finish what sk_free() ++ * could not do because of in-flight packets + */ +- if (res == 0) ++ if (atomic_sub_and_test(len, &sk->sk_wmem_alloc)) + __sk_free(sk); + } + EXPORT_SYMBOL(sock_wfree); diff --git a/review-2.6.31/net-restore-tx-timestamping-for-accelerated-vlans.patch b/review-2.6.31/net-restore-tx-timestamping-for-accelerated-vlans.patch new file mode 100644 index 00000000000..43dc29018e2 --- /dev/null +++ b/review-2.6.31/net-restore-tx-timestamping-for-accelerated-vlans.patch @@ -0,0 +1,55 @@ +From 1244c6f01fc690d2618846fbf568945bd1731454 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 30 Sep 2009 16:42:42 -0700 +Subject: net: restore tx timestamping for accelerated vlans + +From: Eric Dumazet + +[ Upstream commit 81bbb3d4048cf577b5babcb0834230de391a35c5 ] + +Since commit 9b22ea560957de1484e6b3e8538f7eef202e3596 +( net: fix packet socket delivery in rx irq handler ) + +We lost rx timestamping of packets received on accelerated vlans. + +Effect is that tcpdump on real dev can show strange timings, since it gets rx timestamps +too late (ie at skb dequeueing time, not at skb queueing time) + +14:47:26.986871 IP 192.168.20.110 > 192.168.20.141: icmp 64: echo request seq 1 +14:47:26.986786 IP 192.168.20.141 > 192.168.20.110: icmp 64: echo reply seq 1 + +14:47:27.986888 IP 192.168.20.110 > 192.168.20.141: icmp 64: echo request seq 2 +14:47:27.986781 IP 192.168.20.141 > 192.168.20.110: icmp 64: echo reply seq 2 + +14:47:28.986896 IP 192.168.20.110 > 192.168.20.141: icmp 64: echo request seq 3 +14:47:28.986780 IP 192.168.20.141 > 192.168.20.110: icmp 64: echo reply seq 3 + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2248,6 +2248,9 @@ int netif_receive_skb(struct sk_buff *sk + int ret = NET_RX_DROP; + __be16 type; + ++ if (!skb->tstamp.tv64) ++ net_timestamp(skb); ++ + if (skb->vlan_tci && vlan_hwaccel_do_receive(skb)) + return NET_RX_SUCCESS; + +@@ -2255,9 +2258,6 @@ int netif_receive_skb(struct sk_buff *sk + if (netpoll_receive_skb(skb)) + return NET_RX_DROP; + +- if (!skb->tstamp.tv64) +- net_timestamp(skb); +- + if (!skb->iif) + skb->iif = skb->dev->ifindex; + diff --git a/review-2.6.31/net-unix-fix-sending-fds-in-multiple-buffers.patch b/review-2.6.31/net-unix-fix-sending-fds-in-multiple-buffers.patch new file mode 100644 index 00000000000..7d8b253d20c --- /dev/null +++ b/review-2.6.31/net-unix-fix-sending-fds-in-multiple-buffers.patch @@ -0,0 +1,69 @@ +From f599901a049da787808b6df8f876d61bb4ab13b2 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Fri, 11 Sep 2009 11:31:45 -0700 +Subject: net: unix: fix sending fds in multiple buffers + +From: Miklos Szeredi + +[ Upstream commit 8ba69ba6a324b13e1190fc31e41954d190fd4f1d ] + +Kalle Olavi Niemitalo reported that: + + "..., when one process calls sendmsg once to send 43804 bytes of + data and one file descriptor, and another process then calls recvmsg + three times to receive the 16032+16032+11740 bytes, each of those + recvmsg calls returns the file descriptor in the ancillary data. I + confirmed this with strace. The behaviour differs from Linux + 2.6.26, where reportedly only one of those recvmsg calls (I think + the first one) returned the file descriptor." + +This bug was introduced by a patch from me titled "net: unix: fix inflight +counting bug in garbage collector", commit 6209344f5. + +And the reason is, quoting Kalle: + + "Before your patch, unix_attach_fds() would set scm->fp = NULL, so + that if the loop in unix_stream_sendmsg() ran multiple iterations, + it could not call unix_attach_fds() again. But now, + unix_attach_fds() leaves scm->fp unchanged, and I think this causes + it to be called multiple times and duplicate the same file + descriptors to each struct sk_buff." + +Fix this by introducing a flag that is cleared at the start and set +when the fds attached to the first buffer. The resulting code should +work equivalently to the one on 2.6.26. + +Reported-by: Kalle Olavi Niemitalo +Signed-off-by: Miklos Szeredi +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/unix/af_unix.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1501,6 +1501,7 @@ static int unix_stream_sendmsg(struct ki + struct sk_buff *skb; + int sent = 0; + struct scm_cookie tmp_scm; ++ bool fds_sent = false; + + if (NULL == siocb->scm) + siocb->scm = &tmp_scm; +@@ -1562,12 +1563,14 @@ static int unix_stream_sendmsg(struct ki + size = min_t(int, size, skb_tailroom(skb)); + + memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); +- if (siocb->scm->fp) { ++ /* Only send the fds in the first buffer */ ++ if (siocb->scm->fp && !fds_sent) { + err = unix_attach_fds(siocb->scm, skb); + if (err) { + kfree_skb(skb); + goto out_err; + } ++ fds_sent = true; + } + + err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); diff --git a/review-2.6.31/series b/review-2.6.31/series index 807cf50807d..73b2d8ab530 100644 --- a/review-2.6.31/series +++ b/review-2.6.31/series @@ -24,3 +24,14 @@ pit-fixes-to-unbreak-suspend-resume.patch ima-open-new-file-for-read.patch acpi-clarify-resource-conflict-message.patch acpi-fix-compaq-evo-n800c-boot-hang-regression.patch +net-restore-tx-timestamping-for-accelerated-vlans.patch +net-unix-fix-sending-fds-in-multiple-buffers.patch +tun-return-einval-if-neither-iff_tun-nor-iff_tap-is-set.patch +tcp-fix-config_tcp_md5sig-config_preempt-timer-bug.patch +net-fix-sock_wfree-race.patch +smsc95xx-fix-transmission-where-zlp-is-expected.patch +sky2-set-sky2_hw_ram_buffer-in-sky2_init.patch +appletalk-fix-skb-leak-when-ipddp-interface-is-not-loaded.patch +ax25-fix-possible-oops-in-ax25_make_new.patch +ax25-fix-siocax25getinfo-ioctl.patch +sit-fix-off-by-one-in-ipip6_tunnel_get_prl.patch diff --git a/review-2.6.31/sit-fix-off-by-one-in-ipip6_tunnel_get_prl.patch b/review-2.6.31/sit-fix-off-by-one-in-ipip6_tunnel_get_prl.patch new file mode 100644 index 00000000000..b339d99d1af --- /dev/null +++ b/review-2.6.31/sit-fix-off-by-one-in-ipip6_tunnel_get_prl.patch @@ -0,0 +1,34 @@ +From a9cb3db986f8bceaa741175cf016b0b7df59caf0 Mon Sep 17 00:00:00 2001 +From: Sascha Hlusiak +Date: Tue, 29 Sep 2009 11:27:05 +0000 +Subject: sit: fix off-by-one in ipip6_tunnel_get_prl + +From: Sascha Hlusiak + +[ Upstream commit 298bf12ddb25841804f26234a43b89da1b1c0e21 ] + +When requesting all prl entries (kprl.addr == INADDR_ANY) and there are +more prl entries than there is space passed from userspace, the existing +code would always copy cmax+1 entries, which is more than can be handled. + +This patch makes the kernel copy only exactly cmax entries. + +Signed-off-by: Sascha Hlusiak +Acked-By: Fred L. Templin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/sit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -313,7 +313,7 @@ static int ipip6_tunnel_get_prl(struct i + + c = 0; + for (prl = t->prl; prl; prl = prl->next) { +- if (c > cmax) ++ if (c >= cmax) + break; + if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr) + continue; diff --git a/review-2.6.31/sky2-set-sky2_hw_ram_buffer-in-sky2_init.patch b/review-2.6.31/sky2-set-sky2_hw_ram_buffer-in-sky2_init.patch new file mode 100644 index 00000000000..7e1ab8d07da --- /dev/null +++ b/review-2.6.31/sky2-set-sky2_hw_ram_buffer-in-sky2_init.patch @@ -0,0 +1,43 @@ +From c15e9e9c5bf3e5df18ba054050119d084f905499 Mon Sep 17 00:00:00 2001 +From: Mike McCormack +Date: Mon, 21 Sep 2009 04:08:52 +0000 +Subject: sky2: Set SKY2_HW_RAM_BUFFER in sky2_init + +From: Mike McCormack + +[ Upstream commit 74a61ebf653c6abe459f228eb40e9f24f7ef1fb7 ] + +The SKY2_HW_RAM_BUFFER bit in hw->flags was checked in sky2_mac_init(), + before being set later in sky2_up(). + +Setting SKY2_HW_RAM_BUFFER in sky2_init() where other hw->flags are set + should avoid this problem recurring. + +Signed-off-by: Mike McCormack +Acked-by: Stephen Hemminger +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/sky2.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/sky2.c ++++ b/drivers/net/sky2.c +@@ -1455,7 +1455,6 @@ static int sky2_up(struct net_device *de + if (ramsize > 0) { + u32 rxspace; + +- hw->flags |= SKY2_HW_RAM_BUFFER; + pr_debug(PFX "%s: ram buffer %dK\n", dev->name, ramsize); + if (ramsize < 16) + rxspace = ramsize / 2; +@@ -2942,6 +2941,9 @@ static int __devinit sky2_init(struct sk + ++hw->ports; + } + ++ if (sky2_read8(hw, B2_E_0)) ++ hw->flags |= SKY2_HW_RAM_BUFFER; ++ + return 0; + } + diff --git a/review-2.6.31/smsc95xx-fix-transmission-where-zlp-is-expected.patch b/review-2.6.31/smsc95xx-fix-transmission-where-zlp-is-expected.patch new file mode 100644 index 00000000000..3baead6c8d7 --- /dev/null +++ b/review-2.6.31/smsc95xx-fix-transmission-where-zlp-is-expected.patch @@ -0,0 +1,63 @@ +From 710bf937ca93632f2a7e7a7c6a9068c1ff4e4e44 Mon Sep 17 00:00:00 2001 +From: Steve Glendinning +Date: Tue, 22 Sep 2009 04:00:27 +0000 +Subject: smsc95xx: fix transmission where ZLP is expected + +From: Steve Glendinning + +[ Upstream commit ec4756238239f1a331d9fb95bad8b281dad56855 ] + +Usbnet framework assumes USB hardware doesn't handle zero length +packets, but SMSC LAN95xx requires these to be sent for correct +operation. + +This patch fixes an easily reproducible tx lockup when sending a frame +that results in exactly 512 bytes in a USB transmission (e.g. a UDP +frame with 458 data bytes, due to IP headers and our USB headers). It +adds an extra flag to usbnet for the hardware driver to indicate that +it can handle and requires the zero length packets. + +This patch should not affect other usbnet users, please also consider +for -stable. + +Signed-off-by: Steve Glendinning +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/smsc95xx.c | 2 +- + drivers/net/usb/usbnet.c | 2 +- + include/linux/usb/usbnet.h | 1 + + 3 files changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -1232,7 +1232,7 @@ static const struct driver_info smsc95xx + .rx_fixup = smsc95xx_rx_fixup, + .tx_fixup = smsc95xx_tx_fixup, + .status = smsc95xx_status, +- .flags = FLAG_ETHER, ++ .flags = FLAG_ETHER | FLAG_SEND_ZLP, + }; + + static const struct usb_device_id products[] = { +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -988,7 +988,7 @@ int usbnet_start_xmit (struct sk_buff *s + * NOTE: strictly conforming cdc-ether devices should expect + * the ZLP here, but ignore the one-byte packet. + */ +- if ((length % dev->maxpacket) == 0) { ++ if (!(info->flags & FLAG_SEND_ZLP) && (length % dev->maxpacket) == 0) { + urb->transfer_buffer_length++; + if (skb_tailroom(skb)) { + skb->data[skb->len] = 0; +--- a/include/linux/usb/usbnet.h ++++ b/include/linux/usb/usbnet.h +@@ -86,6 +86,7 @@ struct driver_info { + + #define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */ + #define FLAG_WLAN 0x0080 /* use "wlan%d" names */ ++#define FLAG_SEND_ZLP 0x0200 /* hw requires ZLPs are sent */ + + + /* init device ... can sleep, or cause probe() failure */ diff --git a/review-2.6.31/tcp-fix-config_tcp_md5sig-config_preempt-timer-bug.patch b/review-2.6.31/tcp-fix-config_tcp_md5sig-config_preempt-timer-bug.patch new file mode 100644 index 00000000000..3a20ff6fe69 --- /dev/null +++ b/review-2.6.31/tcp-fix-config_tcp_md5sig-config_preempt-timer-bug.patch @@ -0,0 +1,44 @@ +From 362d5749032d6426162f3e545ad353a40f2f0d97 Mon Sep 17 00:00:00 2001 +From: Robert Varga +Date: Tue, 15 Sep 2009 23:49:21 -0700 +Subject: tcp: fix CONFIG_TCP_MD5SIG + CONFIG_PREEMPT timer BUG() + +From: Robert Varga + +[ Upstream commit 657e9649e745b06675aa5063c84430986cdc3afa ] + +I have recently came across a preemption imbalance detected by: + +<4>huh, entered ffffffff80644630 with preempt_count 00000102, exited with 00000101? +<0>------------[ cut here ]------------ +<2>kernel BUG at /usr/src/linux/kernel/timer.c:664! +<0>invalid opcode: 0000 [1] PREEMPT SMP + +with ffffffff80644630 being inet_twdr_hangman(). + +This appeared after I enabled CONFIG_TCP_MD5SIG and played with it a +bit, so I looked at what might have caused it. + +One thing that struck me as strange is tcp_twsk_destructor(), as it +calls tcp_put_md5sig_pool() -- which entails a put_cpu(), causing the +detected imbalance. Found on 2.6.23.9, but 2.6.31 is affected as well, +as far as I can tell. + +Signed-off-by: Robert Varga +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_minisocks.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/tcp_minisocks.c ++++ b/net/ipv4/tcp_minisocks.c +@@ -363,7 +363,7 @@ void tcp_twsk_destructor(struct sock *sk + #ifdef CONFIG_TCP_MD5SIG + struct tcp_timewait_sock *twsk = tcp_twsk(sk); + if (twsk->tw_md5_keylen) +- tcp_put_md5sig_pool(); ++ tcp_free_md5sig_pool(); + #endif + } + diff --git a/review-2.6.31/tun-return-einval-if-neither-iff_tun-nor-iff_tap-is-set.patch b/review-2.6.31/tun-return-einval-if-neither-iff_tun-nor-iff_tap-is-set.patch new file mode 100644 index 00000000000..448e61cea26 --- /dev/null +++ b/review-2.6.31/tun-return-einval-if-neither-iff_tun-nor-iff_tap-is-set.patch @@ -0,0 +1,41 @@ +From c26fb80d1e866f1e50d6702caace1d597bfbb3d0 Mon Sep 17 00:00:00 2001 +From: Kusanagi Kouichi +Date: Wed, 16 Sep 2009 21:36:13 +0000 +Subject: tun: Return -EINVAL if neither IFF_TUN nor IFF_TAP is set. + +From: Kusanagi Kouichi + +[ Upstream commit 36989b90879c785f95b877bdcf65a2527dadd893 ] + +After commit 2b980dbd77d229eb60588802162c9659726b11f4 +("lsm: Add hooks to the TUN driver") tun_set_iff doesn't +return -EINVAL though neither IFF_TUN nor IFF_TAP is set. + +Signed-off-by: Kusanagi Kouichi +Reviewed-by: Paul Moore +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/tun.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -943,8 +943,6 @@ static int tun_set_iff(struct net *net, + char *name; + unsigned long flags = 0; + +- err = -EINVAL; +- + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + +@@ -958,7 +956,7 @@ static int tun_set_iff(struct net *net, + flags |= TUN_TAP_DEV; + name = "tap%d"; + } else +- goto failed; ++ return -EINVAL; + + if (*ifr->ifr_name) + name = ifr->ifr_name;