From 9692054c6de312fb0ba2b5f24c82cd538709a888 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 26 Jul 2014 10:03:39 -0700 Subject: [PATCH] 3.4-stable patches added patches: 8021q-fix-a-potential-memory-leak.patch appletalk-fix-socket-referencing-in-skb.patch be2net-set-eq-db-clear-intr-bit-in-be_open.patch dns_resolver-assure-that-dns_query-result-is-null-terminated.patch dns_resolver-null-terminate-the-right-string.patch igmp-fix-the-problem-when-mc-leave-group.patch ipv4-fix-buffer-overflow-in-ip_options_compile.patch net-pppoe-use-correct-channel-mtu-when-using-multilink-ppp.patch net-sctp-fix-information-leaks-in-ulpevent-layer.patch sunvnet-clean-up-objects-created-in-vnet_new-on-vnet_exit.patch tcp-fix-false-undo-corner-cases.patch tcp-fix-tcp_match_skb_to_sack-for-unaligned-sack-at-end-of-an-skb.patch tipc-clear-next-pointer-of-message-fragments-before-reassembly.patch --- .../8021q-fix-a-potential-memory-leak.patch | 36 +++ ...letalk-fix-socket-referencing-in-skb.patch | 44 +++ ...-set-eq-db-clear-intr-bit-in-be_open.patch | 34 +++ ...-dns_query-result-is-null-terminated.patch | 35 +++ ...lver-null-terminate-the-right-string.patch | 31 +++ ...-fix-the-problem-when-mc-leave-group.patch | 84 ++++++ ...uffer-overflow-in-ip_options_compile.patch | 82 ++++++ ...channel-mtu-when-using-multilink-ppp.patch | 129 +++++++++ ...-information-leaks-in-ulpevent-layer.patch | 256 ++++++++++++++++++ queue-3.4/series | 13 + ...cts-created-in-vnet_new-on-vnet_exit.patch | 69 +++++ .../tcp-fix-false-undo-corner-cases.patch | 96 +++++++ ...-for-unaligned-sack-at-end-of-an-skb.patch | 65 +++++ ...-message-fragments-before-reassembly.patch | 41 +++ 14 files changed, 1015 insertions(+) create mode 100644 queue-3.4/8021q-fix-a-potential-memory-leak.patch create mode 100644 queue-3.4/appletalk-fix-socket-referencing-in-skb.patch create mode 100644 queue-3.4/be2net-set-eq-db-clear-intr-bit-in-be_open.patch create mode 100644 queue-3.4/dns_resolver-assure-that-dns_query-result-is-null-terminated.patch create mode 100644 queue-3.4/dns_resolver-null-terminate-the-right-string.patch create mode 100644 queue-3.4/igmp-fix-the-problem-when-mc-leave-group.patch create mode 100644 queue-3.4/ipv4-fix-buffer-overflow-in-ip_options_compile.patch create mode 100644 queue-3.4/net-pppoe-use-correct-channel-mtu-when-using-multilink-ppp.patch create mode 100644 queue-3.4/net-sctp-fix-information-leaks-in-ulpevent-layer.patch create mode 100644 queue-3.4/sunvnet-clean-up-objects-created-in-vnet_new-on-vnet_exit.patch create mode 100644 queue-3.4/tcp-fix-false-undo-corner-cases.patch create mode 100644 queue-3.4/tcp-fix-tcp_match_skb_to_sack-for-unaligned-sack-at-end-of-an-skb.patch create mode 100644 queue-3.4/tipc-clear-next-pointer-of-message-fragments-before-reassembly.patch diff --git a/queue-3.4/8021q-fix-a-potential-memory-leak.patch b/queue-3.4/8021q-fix-a-potential-memory-leak.patch new file mode 100644 index 00000000000..357a2e10b75 --- /dev/null +++ b/queue-3.4/8021q-fix-a-potential-memory-leak.patch @@ -0,0 +1,36 @@ +From foo@baz Sat Jul 26 10:02:43 PDT 2014 +From: Li RongQing +Date: Wed, 18 Jun 2014 13:46:02 +0800 +Subject: 8021q: fix a potential memory leak + +From: Li RongQing + +[ Upstream commit 916c1689a09bc1ca81f2d7a34876f8d35aadd11b ] + +skb_cow called in vlan_reorder_header does not free the skb when it failed, +and vlan_reorder_header returns NULL to reset original skb when it is called +in vlan_untag, lead to a memory leak. + +Signed-off-by: Li RongQing +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/8021q/vlan_core.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/net/8021q/vlan_core.c ++++ b/net/8021q/vlan_core.c +@@ -96,8 +96,11 @@ EXPORT_SYMBOL(vlan_dev_vlan_id); + + static struct sk_buff *vlan_reorder_header(struct sk_buff *skb) + { +- if (skb_cow(skb, skb_headroom(skb)) < 0) ++ if (skb_cow(skb, skb_headroom(skb)) < 0) { ++ kfree_skb(skb); + return NULL; ++ } ++ + memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN); + skb->mac_header += VLAN_HLEN; + return skb; diff --git a/queue-3.4/appletalk-fix-socket-referencing-in-skb.patch b/queue-3.4/appletalk-fix-socket-referencing-in-skb.patch new file mode 100644 index 00000000000..f1264c759ef --- /dev/null +++ b/queue-3.4/appletalk-fix-socket-referencing-in-skb.patch @@ -0,0 +1,44 @@ +From foo@baz Sat Jul 26 10:02:43 PDT 2014 +From: Andrey Utkin +Date: Mon, 7 Jul 2014 23:22:50 +0300 +Subject: appletalk: Fix socket referencing in skb + +From: Andrey Utkin + +[ Upstream commit 36beddc272c111689f3042bf3d10a64d8a805f93 ] + +Setting just skb->sk without taking its reference and setting a +destructor is invalid. However, in the places where this was done, skb +is used in a way not requiring skb->sk setting. So dropping the setting +of skb->sk. +Thanks to Eric Dumazet for correct solution. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=79441 +Reported-by: Ed Martin +Signed-off-by: Andrey Utkin +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/appletalk/ddp.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/net/appletalk/ddp.c ++++ b/net/appletalk/ddp.c +@@ -1494,8 +1494,6 @@ static int atalk_rcv(struct sk_buff *skb + goto drop; + + /* Queue packet (standard) */ +- skb->sk = sock; +- + if (sock_queue_rcv_skb(sock, skb) < 0) + goto drop; + +@@ -1649,7 +1647,6 @@ static int atalk_sendmsg(struct kiocb *i + if (!skb) + goto out; + +- skb->sk = sk; + skb_reserve(skb, ddp_dl->header_length); + skb_reserve(skb, dev->hard_header_len); + skb->dev = dev; diff --git a/queue-3.4/be2net-set-eq-db-clear-intr-bit-in-be_open.patch b/queue-3.4/be2net-set-eq-db-clear-intr-bit-in-be_open.patch new file mode 100644 index 00000000000..f3e8c5829ad --- /dev/null +++ b/queue-3.4/be2net-set-eq-db-clear-intr-bit-in-be_open.patch @@ -0,0 +1,34 @@ +From foo@baz Sat Jul 26 10:02:43 PDT 2014 +From: Suresh Reddy +Date: Fri, 11 Jul 2014 14:03:01 +0530 +Subject: be2net: set EQ DB clear-intr bit in be_open() + +From: Suresh Reddy + +[ Upstream commit 4cad9f3b61c7268fa89ab8096e23202300399b5d ] + +On BE3, if the clear-interrupt bit of the EQ doorbell is not set the first +time it is armed, ocassionally we have observed that the EQ doesn't raise +anymore interrupts even if it is in armed state. +This patch fixes this by setting the clear-interrupt bit when EQs are +armed for the first time in be_open(). + +Signed-off-by: Suresh Reddy +Signed-off-by: Sathya Perla +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/emulex/benet/be_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/emulex/benet/be_main.c ++++ b/drivers/net/ethernet/emulex/benet/be_main.c +@@ -2411,7 +2411,7 @@ static int be_open(struct net_device *ne + + for_all_evt_queues(adapter, eqo, i) { + napi_enable(&eqo->napi); +- be_eq_notify(adapter, eqo->q.id, true, false, 0); ++ be_eq_notify(adapter, eqo->q.id, true, true, 0); + } + + status = be_cmd_link_status_query(adapter, NULL, NULL, diff --git a/queue-3.4/dns_resolver-assure-that-dns_query-result-is-null-terminated.patch b/queue-3.4/dns_resolver-assure-that-dns_query-result-is-null-terminated.patch new file mode 100644 index 00000000000..082aa42d4d2 --- /dev/null +++ b/queue-3.4/dns_resolver-assure-that-dns_query-result-is-null-terminated.patch @@ -0,0 +1,35 @@ +From foo@baz Sat Jul 26 10:02:43 PDT 2014 +From: =?UTF-8?q?Manuel=20Sch=C3=B6lling?= +Date: Sat, 7 Jun 2014 23:57:25 +0200 +Subject: dns_resolver: assure that dns_query() result is null-terminated +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Manuel=20Sch=C3=B6lling?= + +[ Upstream commit 84a7c0b1db1c17d5ded8d3800228a608e1070b40 ] + +dns_query() credulously assumes that keys are null-terminated and +returns a copy of a memory block that is off by one. + +Signed-off-by: Manuel Schölling +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/dns_resolver/dns_query.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/dns_resolver/dns_query.c ++++ b/net/dns_resolver/dns_query.c +@@ -150,7 +150,9 @@ int dns_query(const char *type, const ch + if (!*_result) + goto put; + +- memcpy(*_result, upayload->data, len + 1); ++ memcpy(*_result, upayload->data, len); ++ *_result[len] = '\0'; ++ + if (_expiry) + *_expiry = rkey->expiry; + diff --git a/queue-3.4/dns_resolver-null-terminate-the-right-string.patch b/queue-3.4/dns_resolver-null-terminate-the-right-string.patch new file mode 100644 index 00000000000..171d0b516ca --- /dev/null +++ b/queue-3.4/dns_resolver-null-terminate-the-right-string.patch @@ -0,0 +1,31 @@ +From foo@baz Sat Jul 26 10:02:43 PDT 2014 +From: Ben Hutchings +Date: Mon, 21 Jul 2014 00:06:48 +0100 +Subject: dns_resolver: Null-terminate the right string + +From: Ben Hutchings + +[ Upstream commit 640d7efe4c08f06c4ae5d31b79bd8740e7f6790a ] + +*_result[len] is parsed as *(_result[len]) which is not at all what we +want to touch here. + +Signed-off-by: Ben Hutchings +Fixes: 84a7c0b1db1c ("dns_resolver: assure that dns_query() result is null-terminated") +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/dns_resolver/dns_query.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/dns_resolver/dns_query.c ++++ b/net/dns_resolver/dns_query.c +@@ -151,7 +151,7 @@ int dns_query(const char *type, const ch + goto put; + + memcpy(*_result, upayload->data, len); +- *_result[len] = '\0'; ++ (*_result)[len] = '\0'; + + if (_expiry) + *_expiry = rkey->expiry; diff --git a/queue-3.4/igmp-fix-the-problem-when-mc-leave-group.patch b/queue-3.4/igmp-fix-the-problem-when-mc-leave-group.patch new file mode 100644 index 00000000000..add8e2c235c --- /dev/null +++ b/queue-3.4/igmp-fix-the-problem-when-mc-leave-group.patch @@ -0,0 +1,84 @@ +From foo@baz Sat Jul 26 10:02:43 PDT 2014 +From: dingtianhong +Date: Wed, 2 Jul 2014 13:50:48 +0800 +Subject: igmp: fix the problem when mc leave group + +From: dingtianhong + +[ Upstream commit 52ad353a5344f1f700c5b777175bdfa41d3cd65a ] + +The problem was triggered by these steps: + +1) create socket, bind and then setsockopt for add mc group. + mreq.imr_multiaddr.s_addr = inet_addr("255.0.0.37"); + mreq.imr_interface.s_addr = inet_addr("192.168.1.2"); + setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); + +2) drop the mc group for this socket. + mreq.imr_multiaddr.s_addr = inet_addr("255.0.0.37"); + mreq.imr_interface.s_addr = inet_addr("0.0.0.0"); + setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); + +3) and then drop the socket, I found the mc group was still used by the dev: + + netstat -g + + Interface RefCnt Group + --------------- ------ --------------------- + eth2 1 255.0.0.37 + +Normally even though the IP_DROP_MEMBERSHIP return error, the mc group still need +to be released for the netdev when drop the socket, but this process was broken when +route default is NULL, the reason is that: + +The ip_mc_leave_group() will choose the in_dev by the imr_interface.s_addr, if input addr +is NULL, the default route dev will be chosen, then the ifindex is got from the dev, +then polling the inet->mc_list and return -ENODEV, but if the default route dev is NULL, +the in_dev and ifIndex is both NULL, when polling the inet->mc_list, the mc group will be +released from the mc_list, but the dev didn't dec the refcnt for this mc group, so +when dropping the socket, the mc_list is NULL and the dev still keep this group. + +v1->v2: According Hideaki's suggestion, we should align with IPv6 (RFC3493) and BSDs, + so I add the checking for the in_dev before polling the mc_list, make sure when + we remove the mc group, dec the refcnt to the real dev which was using the mc address. + The problem would never happened again. + +Signed-off-by: Ding Tianhong +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/igmp.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -1866,6 +1866,10 @@ int ip_mc_leave_group(struct sock *sk, s + + rtnl_lock(); + in_dev = ip_mc_find_dev(net, imr); ++ if (!in_dev) { ++ ret = -ENODEV; ++ goto out; ++ } + ifindex = imr->imr_ifindex; + for (imlp = &inet->mc_list; + (iml = rtnl_dereference(*imlp)) != NULL; +@@ -1883,16 +1887,14 @@ int ip_mc_leave_group(struct sock *sk, s + + *imlp = iml->next_rcu; + +- if (in_dev) +- ip_mc_dec_group(in_dev, group); ++ ip_mc_dec_group(in_dev, group); + rtnl_unlock(); + /* decrease mem now to avoid the memleak warning */ + atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); + kfree_rcu(iml, rcu); + return 0; + } +- if (!in_dev) +- ret = -ENODEV; ++out: + rtnl_unlock(); + return ret; + } diff --git a/queue-3.4/ipv4-fix-buffer-overflow-in-ip_options_compile.patch b/queue-3.4/ipv4-fix-buffer-overflow-in-ip_options_compile.patch new file mode 100644 index 00000000000..88769de57e4 --- /dev/null +++ b/queue-3.4/ipv4-fix-buffer-overflow-in-ip_options_compile.patch @@ -0,0 +1,82 @@ +From foo@baz Sat Jul 26 10:02:43 PDT 2014 +From: Eric Dumazet +Date: Mon, 21 Jul 2014 07:17:42 +0200 +Subject: ipv4: fix buffer overflow in ip_options_compile() + +From: Eric Dumazet + +[ Upstream commit 10ec9472f05b45c94db3c854d22581a20b97db41 ] + +There is a benign buffer overflow in ip_options_compile spotted by +AddressSanitizer[1] : + +Its benign because we always can access one extra byte in skb->head +(because header is followed by struct skb_shared_info), and in this case +this byte is not even used. + +[28504.910798] ================================================================== +[28504.912046] AddressSanitizer: heap-buffer-overflow in ip_options_compile +[28504.913170] Read of size 1 by thread T15843: +[28504.914026] [] ip_options_compile+0x121/0x9c0 +[28504.915394] [] ip_options_get_from_user+0xad/0x120 +[28504.916843] [] do_ip_setsockopt.isra.15+0x8df/0x1630 +[28504.918175] [] ip_setsockopt+0x30/0xa0 +[28504.919490] [] tcp_setsockopt+0x5b/0x90 +[28504.920835] [] sock_common_setsockopt+0x5f/0x70 +[28504.922208] [] SyS_setsockopt+0xa2/0x140 +[28504.923459] [] system_call_fastpath+0x16/0x1b +[28504.924722] +[28504.925106] Allocated by thread T15843: +[28504.925815] [] ip_options_get_from_user+0x35/0x120 +[28504.926884] [] do_ip_setsockopt.isra.15+0x8df/0x1630 +[28504.927975] [] ip_setsockopt+0x30/0xa0 +[28504.929175] [] tcp_setsockopt+0x5b/0x90 +[28504.930400] [] sock_common_setsockopt+0x5f/0x70 +[28504.931677] [] SyS_setsockopt+0xa2/0x140 +[28504.932851] [] system_call_fastpath+0x16/0x1b +[28504.934018] +[28504.934377] The buggy address ffff880026382828 is located 0 bytes to the right +[28504.934377] of 40-byte region [ffff880026382800, ffff880026382828) +[28504.937144] +[28504.937474] Memory state around the buggy address: +[28504.938430] ffff880026382300: ........ rrrrrrrr rrrrrrrr rrrrrrrr +[28504.939884] ffff880026382400: ffffffff rrrrrrrr rrrrrrrr rrrrrrrr +[28504.941294] ffff880026382500: .....rrr rrrrrrrr rrrrrrrr rrrrrrrr +[28504.942504] ffff880026382600: ffffffff rrrrrrrr rrrrrrrr rrrrrrrr +[28504.943483] ffff880026382700: ffffffff rrrrrrrr rrrrrrrr rrrrrrrr +[28504.944511] >ffff880026382800: .....rrr rrrrrrrr rrrrrrrr rrrrrrrr +[28504.945573] ^ +[28504.946277] ffff880026382900: ffffffff rrrrrrrr rrrrrrrr rrrrrrrr +[28505.094949] ffff880026382a00: ffffffff rrrrrrrr rrrrrrrr rrrrrrrr +[28505.096114] ffff880026382b00: ffffffff rrrrrrrr rrrrrrrr rrrrrrrr +[28505.097116] ffff880026382c00: ffffffff rrrrrrrr rrrrrrrr rrrrrrrr +[28505.098472] ffff880026382d00: ffffffff rrrrrrrr rrrrrrrr rrrrrrrr +[28505.099804] Legend: +[28505.100269] f - 8 freed bytes +[28505.100884] r - 8 redzone bytes +[28505.101649] . - 8 allocated bytes +[28505.102406] x=1..7 - x allocated bytes + (8-x) redzone bytes +[28505.103637] ================================================================== + +[1] https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_options.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/ipv4/ip_options.c ++++ b/net/ipv4/ip_options.c +@@ -279,6 +279,10 @@ int ip_options_compile(struct net *net, + optptr++; + continue; + } ++ if (unlikely(l < 2)) { ++ pp_ptr = optptr; ++ goto error; ++ } + optlen = optptr[1]; + if (optlen<2 || optlen>l) { + pp_ptr = optptr; diff --git a/queue-3.4/net-pppoe-use-correct-channel-mtu-when-using-multilink-ppp.patch b/queue-3.4/net-pppoe-use-correct-channel-mtu-when-using-multilink-ppp.patch new file mode 100644 index 00000000000..5f310dd9e25 --- /dev/null +++ b/queue-3.4/net-pppoe-use-correct-channel-mtu-when-using-multilink-ppp.patch @@ -0,0 +1,129 @@ +From foo@baz Sat Jul 26 10:02:43 PDT 2014 +From: Christoph Schulz +Date: Sun, 13 Jul 2014 00:53:15 +0200 +Subject: net: pppoe: use correct channel MTU when using Multilink PPP + +From: Christoph Schulz + +[ Upstream commit a8a3e41c67d24eb12f9ab9680cbb85e24fcd9711 ] + +The PPP channel MTU is used with Multilink PPP when ppp_mp_explode() (see +ppp_generic module) tries to determine how big a fragment might be. According +to RFC 1661, the MTU excludes the 2-byte PPP protocol field, see the +corresponding comment and code in ppp_mp_explode(): + + /* + * hdrlen includes the 2-byte PPP protocol field, but the + * MTU counts only the payload excluding the protocol field. + * (RFC1661 Section 2) + */ + mtu = pch->chan->mtu - (hdrlen - 2); + +However, the pppoe module *does* include the PPP protocol field in the channel +MTU, which is wrong as it causes the PPP payload to be 1-2 bytes too big under +certain circumstances (one byte if PPP protocol compression is used, two +otherwise), causing the generated Ethernet packets to be dropped. So the pppoe +module has to subtract two bytes from the channel MTU. This error only +manifests itself when using Multilink PPP, as otherwise the channel MTU is not +used anywhere. + +In the following, I will describe how to reproduce this bug. We configure two +pppd instances for multilink PPP over two PPPoE links, say eth2 and eth3, with +a MTU of 1492 bytes for each link and a MRRU of 2976 bytes. (This MRRU is +computed by adding the two link MTUs and subtracting the MP header twice, which +is 4 bytes long.) The necessary pppd statements on both sides are "multilink +mtu 1492 mru 1492 mrru 2976". On the client side, we additionally need "plugin +rp-pppoe.so eth2" and "plugin rp-pppoe.so eth3", respectively; on the server +side, we additionally need to start two pppoe-server instances to be able to +establish two PPPoE sessions, one over eth2 and one over eth3. We set the MTU +of the PPP network interface to the MRRU (2976) on both sides of the connection +in order to make use of the higher bandwidth. (If we didn't do that, IP +fragmentation would kick in, which we want to avoid.) + +Now we send a ICMPv4 echo request with a payload of 2948 bytes from client to +server over the PPP link. This results in the following network packet: + + 2948 (echo payload) + + 8 (ICMPv4 header) + + 20 (IPv4 header) +--------------------- + 2976 (PPP payload) + +These 2976 bytes do not exceed the MTU of the PPP network interface, so the +IP packet is not fragmented. Now the multilink PPP code in ppp_mp_explode() +prepends one protocol byte (0x21 for IPv4), making the packet one byte bigger +than the negotiated MRRU. So this packet would have to be divided in three +fragments. But this does not happen as each link MTU is assumed to be two bytes +larger. So this packet is diveded into two fragments only, one of size 1489 and +one of size 1488. Now we have for that bigger fragment: + + 1489 (PPP payload) + + 4 (MP header) + + 2 (PPP protocol field for the MP payload (0x3d)) + + 6 (PPPoE header) +-------------------------- + 1501 (Ethernet payload) + +This packet exceeds the link MTU and is discarded. + +If one configures the link MTU on the client side to 1501, one can see the +discarded Ethernet frames with tcpdump running on the client. A + +ping -s 2948 -c 1 192.168.15.254 + +leads to the smaller fragment that is correctly received on the server side: + +(tcpdump -vvvne -i eth3 pppoes and ppp proto 0x3d) +52:54:00:ad:87:fd > 52:54:00:79:5c:d0, ethertype PPPoE S (0x8864), + length 1514: PPPoE [ses 0x3] MLPPP (0x003d), length 1494: seq 0x000, + Flags [end], length 1492 + +and to the bigger fragment that is not received on the server side: + +(tcpdump -vvvne -i eth2 pppoes and ppp proto 0x3d) +52:54:00:70:9e:89 > 52:54:00:5d:6f:b0, ethertype PPPoE S (0x8864), + length 1515: PPPoE [ses 0x5] MLPPP (0x003d), length 1495: seq 0x000, + Flags [begin], length 1493 + +With the patch below, we correctly obtain three fragments: + +52:54:00:ad:87:fd > 52:54:00:79:5c:d0, ethertype PPPoE S (0x8864), + length 1514: PPPoE [ses 0x1] MLPPP (0x003d), length 1494: seq 0x000, + Flags [begin], length 1492 +52:54:00:70:9e:89 > 52:54:00:5d:6f:b0, ethertype PPPoE S (0x8864), + length 1514: PPPoE [ses 0x1] MLPPP (0x003d), length 1494: seq 0x000, + Flags [none], length 1492 +52:54:00:ad:87:fd > 52:54:00:79:5c:d0, ethertype PPPoE S (0x8864), + length 27: PPPoE [ses 0x1] MLPPP (0x003d), length 7: seq 0x000, + Flags [end], length 5 + +And the ICMPv4 echo request is successfully received at the server side: + +IP (tos 0x0, ttl 64, id 21925, offset 0, flags [DF], proto ICMP (1), + length 2976) + 192.168.222.2 > 192.168.15.254: ICMP echo request, id 30530, seq 0, + length 2956 + +The bug was introduced in commit c9aa6895371b2a257401f59d3393c9f7ac5a8698 +("[PPPOE]: Advertise PPPoE MTU") from the very beginning. This patch applies +to 3.10 upwards but the fix can be applied (with minor modifications) to +kernels as old as 2.6.32. + +Signed-off-by: Christoph Schulz +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ppp/pppoe.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ppp/pppoe.c ++++ b/drivers/net/ppp/pppoe.c +@@ -681,7 +681,7 @@ static int pppoe_connect(struct socket * + po->chan.hdrlen = (sizeof(struct pppoe_hdr) + + dev->hard_header_len); + +- po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr); ++ po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2; + po->chan.private = sk; + po->chan.ops = &pppoe_chan_ops; + diff --git a/queue-3.4/net-sctp-fix-information-leaks-in-ulpevent-layer.patch b/queue-3.4/net-sctp-fix-information-leaks-in-ulpevent-layer.patch new file mode 100644 index 00000000000..3a55bb0ea3b --- /dev/null +++ b/queue-3.4/net-sctp-fix-information-leaks-in-ulpevent-layer.patch @@ -0,0 +1,256 @@ +From foo@baz Sat Jul 26 10:02:43 PDT 2014 +From: Daniel Borkmann +Date: Sat, 12 Jul 2014 20:30:35 +0200 +Subject: net: sctp: fix information leaks in ulpevent layer + +From: Daniel Borkmann + +[ Upstream commit 8f2e5ae40ec193bc0a0ed99e95315c3eebca84ea ] + +While working on some other SCTP code, I noticed that some +structures shared with user space are leaking uninitialized +stack or heap buffer. In particular, struct sctp_sndrcvinfo +has a 2 bytes hole between .sinfo_flags and .sinfo_ppid that +remains unfilled by us in sctp_ulpevent_read_sndrcvinfo() when +putting this into cmsg. But also struct sctp_remote_error +contains a 2 bytes hole that we don't fill but place into a skb +through skb_copy_expand() via sctp_ulpevent_make_remote_error(). + +Both structures are defined by the IETF in RFC6458: + +* Section 5.3.2. SCTP Header Information Structure: + + The sctp_sndrcvinfo structure is defined below: + + struct sctp_sndrcvinfo { + uint16_t sinfo_stream; + uint16_t sinfo_ssn; + uint16_t sinfo_flags; + <-- 2 bytes hole --> + uint32_t sinfo_ppid; + uint32_t sinfo_context; + uint32_t sinfo_timetolive; + uint32_t sinfo_tsn; + uint32_t sinfo_cumtsn; + sctp_assoc_t sinfo_assoc_id; + }; + +* 6.1.3. SCTP_REMOTE_ERROR: + + A remote peer may send an Operation Error message to its peer. + This message indicates a variety of error conditions on an + association. The entire ERROR chunk as it appears on the wire + is included in an SCTP_REMOTE_ERROR event. Please refer to the + SCTP specification [RFC4960] and any extensions for a list of + possible error formats. An SCTP error notification has the + following format: + + struct sctp_remote_error { + uint16_t sre_type; + uint16_t sre_flags; + uint32_t sre_length; + uint16_t sre_error; + <-- 2 bytes hole --> + sctp_assoc_t sre_assoc_id; + uint8_t sre_data[]; + }; + +Fix this by setting both to 0 before filling them out. We also +have other structures shared between user and kernel space in +SCTP that contains holes (e.g. struct sctp_paddrthlds), but we +copy that buffer over from user space first and thus don't need +to care about it in that cases. + +While at it, we can also remove lengthy comments copied from +the draft, instead, we update the comment with the correct RFC +number where one can look it up. + +Signed-off-by: Daniel Borkmann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/ulpevent.c | 122 ++++++---------------------------------------------- + 1 file changed, 15 insertions(+), 107 deletions(-) + +--- a/net/sctp/ulpevent.c ++++ b/net/sctp/ulpevent.c +@@ -373,9 +373,10 @@ fail: + * specification [SCTP] and any extensions for a list of possible + * error formats. + */ +-struct sctp_ulpevent *sctp_ulpevent_make_remote_error( +- const struct sctp_association *asoc, struct sctp_chunk *chunk, +- __u16 flags, gfp_t gfp) ++struct sctp_ulpevent * ++sctp_ulpevent_make_remote_error(const struct sctp_association *asoc, ++ struct sctp_chunk *chunk, __u16 flags, ++ gfp_t gfp) + { + struct sctp_ulpevent *event; + struct sctp_remote_error *sre; +@@ -394,8 +395,7 @@ struct sctp_ulpevent *sctp_ulpevent_make + /* Copy the skb to a new skb with room for us to prepend + * notification with. + */ +- skb = skb_copy_expand(chunk->skb, sizeof(struct sctp_remote_error), +- 0, gfp); ++ skb = skb_copy_expand(chunk->skb, sizeof(*sre), 0, gfp); + + /* Pull off the rest of the cause TLV from the chunk. */ + skb_pull(chunk->skb, elen); +@@ -406,62 +406,21 @@ struct sctp_ulpevent *sctp_ulpevent_make + event = sctp_skb2event(skb); + sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize); + +- sre = (struct sctp_remote_error *) +- skb_push(skb, sizeof(struct sctp_remote_error)); ++ sre = (struct sctp_remote_error *) skb_push(skb, sizeof(*sre)); + + /* Trim the buffer to the right length. */ +- skb_trim(skb, sizeof(struct sctp_remote_error) + elen); ++ skb_trim(skb, sizeof(*sre) + elen); + +- /* Socket Extensions for SCTP +- * 5.3.1.3 SCTP_REMOTE_ERROR +- * +- * sre_type: +- * It should be SCTP_REMOTE_ERROR. +- */ ++ /* RFC6458, Section 6.1.3. SCTP_REMOTE_ERROR */ ++ memset(sre, 0, sizeof(*sre)); + sre->sre_type = SCTP_REMOTE_ERROR; +- +- /* +- * Socket Extensions for SCTP +- * 5.3.1.3 SCTP_REMOTE_ERROR +- * +- * sre_flags: 16 bits (unsigned integer) +- * Currently unused. +- */ + sre->sre_flags = 0; +- +- /* Socket Extensions for SCTP +- * 5.3.1.3 SCTP_REMOTE_ERROR +- * +- * sre_length: sizeof (__u32) +- * +- * This field is the total length of the notification data, +- * including the notification header. +- */ + sre->sre_length = skb->len; +- +- /* Socket Extensions for SCTP +- * 5.3.1.3 SCTP_REMOTE_ERROR +- * +- * sre_error: 16 bits (unsigned integer) +- * This value represents one of the Operational Error causes defined in +- * the SCTP specification, in network byte order. +- */ + sre->sre_error = cause; +- +- /* Socket Extensions for SCTP +- * 5.3.1.3 SCTP_REMOTE_ERROR +- * +- * sre_assoc_id: sizeof (sctp_assoc_t) +- * +- * The association id field, holds the identifier for the association. +- * All notifications for a given association have the same association +- * identifier. For TCP style socket, this field is ignored. +- */ + sctp_ulpevent_set_owner(event, asoc); + sre->sre_assoc_id = sctp_assoc2id(asoc); + + return event; +- + fail: + return NULL; + } +@@ -904,7 +863,9 @@ __u16 sctp_ulpevent_get_notification_typ + return notification->sn_header.sn_type; + } + +-/* Copy out the sndrcvinfo into a msghdr. */ ++/* RFC6458, Section 5.3.2. SCTP Header Information Structure ++ * (SCTP_SNDRCV, DEPRECATED) ++ */ + void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, + struct msghdr *msghdr) + { +@@ -913,74 +874,21 @@ void sctp_ulpevent_read_sndrcvinfo(const + if (sctp_ulpevent_is_notification(event)) + return; + +- /* Sockets API Extensions for SCTP +- * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) +- * +- * sinfo_stream: 16 bits (unsigned integer) +- * +- * For recvmsg() the SCTP stack places the message's stream number in +- * this value. +- */ ++ memset(&sinfo, 0, sizeof(sinfo)); + sinfo.sinfo_stream = event->stream; +- /* sinfo_ssn: 16 bits (unsigned integer) +- * +- * For recvmsg() this value contains the stream sequence number that +- * the remote endpoint placed in the DATA chunk. For fragmented +- * messages this is the same number for all deliveries of the message +- * (if more than one recvmsg() is needed to read the message). +- */ + sinfo.sinfo_ssn = event->ssn; +- /* sinfo_ppid: 32 bits (unsigned integer) +- * +- * In recvmsg() this value is +- * the same information that was passed by the upper layer in the peer +- * application. Please note that byte order issues are NOT accounted +- * for and this information is passed opaquely by the SCTP stack from +- * one end to the other. +- */ + sinfo.sinfo_ppid = event->ppid; +- /* sinfo_flags: 16 bits (unsigned integer) +- * +- * This field may contain any of the following flags and is composed of +- * a bitwise OR of these values. +- * +- * recvmsg() flags: +- * +- * SCTP_UNORDERED - This flag is present when the message was sent +- * non-ordered. +- */ + sinfo.sinfo_flags = event->flags; +- /* sinfo_tsn: 32 bit (unsigned integer) +- * +- * For the receiving side, this field holds a TSN that was +- * assigned to one of the SCTP Data Chunks. +- */ + sinfo.sinfo_tsn = event->tsn; +- /* sinfo_cumtsn: 32 bit (unsigned integer) +- * +- * This field will hold the current cumulative TSN as +- * known by the underlying SCTP layer. Note this field is +- * ignored when sending and only valid for a receive +- * operation when sinfo_flags are set to SCTP_UNORDERED. +- */ + sinfo.sinfo_cumtsn = event->cumtsn; +- /* sinfo_assoc_id: sizeof (sctp_assoc_t) +- * +- * The association handle field, sinfo_assoc_id, holds the identifier +- * for the association announced in the COMMUNICATION_UP notification. +- * All notifications for a given association have the same identifier. +- * Ignored for one-to-one style sockets. +- */ + sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc); +- +- /* context value that is set via SCTP_CONTEXT socket option. */ ++ /* Context value that is set via SCTP_CONTEXT socket option. */ + sinfo.sinfo_context = event->asoc->default_rcv_context; +- + /* These fields are not used while receiving. */ + sinfo.sinfo_timetolive = 0; + + put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV, +- sizeof(struct sctp_sndrcvinfo), (void *)&sinfo); ++ sizeof(sinfo), &sinfo); + } + + /* Do accounting for bytes received and hold a reference to the association diff --git a/queue-3.4/series b/queue-3.4/series index 28c02c9e044..68986d66514 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -2,3 +2,16 @@ crypto-testmgr-update-lzo-compression-test-vectors.patch shmem-fix-faulting-into-a-hole-while-it-s-punched.patch shmem-fix-faulting-into-a-hole-not-taking-i_mutex.patch shmem-fix-splicing-from-a-hole-while-it-s-punched.patch +tcp-fix-tcp_match_skb_to_sack-for-unaligned-sack-at-end-of-an-skb.patch +8021q-fix-a-potential-memory-leak.patch +igmp-fix-the-problem-when-mc-leave-group.patch +tcp-fix-false-undo-corner-cases.patch +appletalk-fix-socket-referencing-in-skb.patch +be2net-set-eq-db-clear-intr-bit-in-be_open.patch +tipc-clear-next-pointer-of-message-fragments-before-reassembly.patch +net-sctp-fix-information-leaks-in-ulpevent-layer.patch +net-pppoe-use-correct-channel-mtu-when-using-multilink-ppp.patch +sunvnet-clean-up-objects-created-in-vnet_new-on-vnet_exit.patch +dns_resolver-assure-that-dns_query-result-is-null-terminated.patch +dns_resolver-null-terminate-the-right-string.patch +ipv4-fix-buffer-overflow-in-ip_options_compile.patch diff --git a/queue-3.4/sunvnet-clean-up-objects-created-in-vnet_new-on-vnet_exit.patch b/queue-3.4/sunvnet-clean-up-objects-created-in-vnet_new-on-vnet_exit.patch new file mode 100644 index 00000000000..dcd71be2dcc --- /dev/null +++ b/queue-3.4/sunvnet-clean-up-objects-created-in-vnet_new-on-vnet_exit.patch @@ -0,0 +1,69 @@ +From foo@baz Sat Jul 26 10:02:43 PDT 2014 +From: Sowmini Varadhan +Date: Wed, 16 Jul 2014 10:02:26 -0400 +Subject: sunvnet: clean up objects created in vnet_new() on vnet_exit() + +From: Sowmini Varadhan + +[ Upstream commit a4b70a07ed12a71131cab7adce2ce91c71b37060 ] + +Nothing cleans up the objects created by +vnet_new(), they are completely leaked. + +vnet_exit(), after doing the vio_unregister_driver() to clean +up ports, should call a helper function that iterates over vnet_list +and cleans up those objects. This includes unregister_netdevice() +as well as free_netdev(). + +Signed-off-by: Sowmini Varadhan +Acked-by: Dave Kleikamp +Reviewed-by: Karl Volz +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/sun/sunvnet.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/sun/sunvnet.c ++++ b/drivers/net/ethernet/sun/sunvnet.c +@@ -1086,6 +1086,24 @@ static struct vnet * __devinit vnet_find + return vp; + } + ++static void vnet_cleanup(void) ++{ ++ struct vnet *vp; ++ struct net_device *dev; ++ ++ mutex_lock(&vnet_list_mutex); ++ while (!list_empty(&vnet_list)) { ++ vp = list_first_entry(&vnet_list, struct vnet, list); ++ list_del(&vp->list); ++ dev = vp->dev; ++ /* vio_unregister_driver() should have cleaned up port_list */ ++ BUG_ON(!list_empty(&vp->port_list)); ++ unregister_netdev(dev); ++ free_netdev(dev); ++ } ++ mutex_unlock(&vnet_list_mutex); ++} ++ + static const char *local_mac_prop = "local-mac-address"; + + static struct vnet * __devinit vnet_find_parent(struct mdesc_handle *hp, +@@ -1244,7 +1262,6 @@ static int vnet_port_remove(struct vio_d + + kfree(port); + +- unregister_netdev(vp->dev); + } + return 0; + } +@@ -1272,6 +1289,7 @@ static int __init vnet_init(void) + static void __exit vnet_exit(void) + { + vio_unregister_driver(&vnet_port_driver); ++ vnet_cleanup(); + } + + module_init(vnet_init); diff --git a/queue-3.4/tcp-fix-false-undo-corner-cases.patch b/queue-3.4/tcp-fix-false-undo-corner-cases.patch new file mode 100644 index 00000000000..a358e8eecb8 --- /dev/null +++ b/queue-3.4/tcp-fix-false-undo-corner-cases.patch @@ -0,0 +1,96 @@ +From foo@baz Sat Jul 26 10:02:43 PDT 2014 +From: Yuchung Cheng +Date: Wed, 2 Jul 2014 12:07:16 -0700 +Subject: tcp: fix false undo corner cases + +From: Yuchung Cheng + +[ Upstream commit 6e08d5e3c8236e7484229e46fdf92006e1dd4c49 ] + +The undo code assumes that, upon entering loss recovery, TCP +1) always retransmit something +2) the retransmission never fails locally (e.g., qdisc drop) + +so undo_marker is set in tcp_enter_recovery() and undo_retrans is +incremented only when tcp_retransmit_skb() is successful. + +When the assumption is broken because TCP's cwnd is too small to +retransmit or the retransmit fails locally. The next (DUP)ACK +would incorrectly revert the cwnd and the congestion state in +tcp_try_undo_dsack() or tcp_may_undo(). Subsequent (DUP)ACKs +may enter the recovery state. The sender repeatedly enter and +(incorrectly) exit recovery states if the retransmits continue to +fail locally while receiving (DUP)ACKs. + +The fix is to initialize undo_retrans to -1 and start counting on +the first retransmission. Always increment undo_retrans even if the +retransmissions fail locally because they couldn't cause DSACKs to +undo the cwnd reduction. + +Signed-off-by: Yuchung Cheng +Signed-off-by: Neal Cardwell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_input.c | 8 ++++---- + net/ipv4/tcp_output.c | 6 ++++-- + 2 files changed, 8 insertions(+), 6 deletions(-) + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -1250,7 +1250,7 @@ static int tcp_check_dsack(struct sock * + } + + /* D-SACK for already forgotten data... Do dumb counting. */ +- if (dup_sack && tp->undo_marker && tp->undo_retrans && ++ if (dup_sack && tp->undo_marker && tp->undo_retrans > 0 && + !after(end_seq_0, prior_snd_una) && + after(end_seq_0, tp->undo_marker)) + tp->undo_retrans--; +@@ -1328,7 +1328,7 @@ static u8 tcp_sacktag_one(struct sock *s + + /* Account D-SACK for retransmitted packet. */ + if (dup_sack && (sacked & TCPCB_RETRANS)) { +- if (tp->undo_marker && tp->undo_retrans && ++ if (tp->undo_marker && tp->undo_retrans > 0 && + after(end_seq, tp->undo_marker)) + tp->undo_retrans--; + if (sacked & TCPCB_SACKED_ACKED) +@@ -2226,7 +2226,7 @@ static void tcp_clear_retrans_partial(st + tp->lost_out = 0; + + tp->undo_marker = 0; +- tp->undo_retrans = 0; ++ tp->undo_retrans = -1; + } + + void tcp_clear_retrans(struct tcp_sock *tp) +@@ -3165,7 +3165,7 @@ static void tcp_fastretrans_alert(struct + tp->high_seq = tp->snd_nxt; + tp->prior_ssthresh = 0; + tp->undo_marker = tp->snd_una; +- tp->undo_retrans = tp->retrans_out; ++ tp->undo_retrans = tp->retrans_out ? : -1; + + if (icsk->icsk_ca_state < TCP_CA_CWR) { + if (!(flag & FLAG_ECE)) +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -2194,13 +2194,15 @@ int tcp_retransmit_skb(struct sock *sk, + if (!tp->retrans_stamp) + tp->retrans_stamp = TCP_SKB_CB(skb)->when; + +- tp->undo_retrans += tcp_skb_pcount(skb); +- + /* snd_nxt is stored to detect loss of retransmitted segment, + * see tcp_input.c tcp_sacktag_write_queue(). + */ + TCP_SKB_CB(skb)->ack_seq = tp->snd_nxt; + } ++ ++ if (tp->undo_retrans < 0) ++ tp->undo_retrans = 0; ++ tp->undo_retrans += tcp_skb_pcount(skb); + return err; + } + diff --git a/queue-3.4/tcp-fix-tcp_match_skb_to_sack-for-unaligned-sack-at-end-of-an-skb.patch b/queue-3.4/tcp-fix-tcp_match_skb_to_sack-for-unaligned-sack-at-end-of-an-skb.patch new file mode 100644 index 00000000000..f56a4f23ad7 --- /dev/null +++ b/queue-3.4/tcp-fix-tcp_match_skb_to_sack-for-unaligned-sack-at-end-of-an-skb.patch @@ -0,0 +1,65 @@ +From foo@baz Sat Jul 26 10:02:43 PDT 2014 +From: Neal Cardwell +Date: Wed, 18 Jun 2014 21:15:03 -0400 +Subject: tcp: fix tcp_match_skb_to_sack() for unaligned SACK at end of an skb + +From: Neal Cardwell + +[ Upstream commit 2cd0d743b05e87445c54ca124a9916f22f16742e ] + +If there is an MSS change (or misbehaving receiver) that causes a SACK +to arrive that covers the end of an skb but is less than one MSS, then +tcp_match_skb_to_sack() was rounding up pkt_len to the full length of +the skb ("Round if necessary..."), then chopping all bytes off the skb +and creating a zero-byte skb in the write queue. + +This was visible now because the recently simplified TLP logic in +bef1909ee3ed1c ("tcp: fixing TLP's FIN recovery") could find that 0-byte +skb at the end of the write queue, and now that we do not check that +skb's length we could send it as a TLP probe. + +Consider the following example scenario: + + mss: 1000 + skb: seq: 0 end_seq: 4000 len: 4000 + SACK: start_seq: 3999 end_seq: 4000 + +The tcp_match_skb_to_sack() code will compute: + + in_sack = false + pkt_len = start_seq - TCP_SKB_CB(skb)->seq = 3999 - 0 = 3999 + new_len = (pkt_len / mss) * mss = (3999/1000)*1000 = 3000 + new_len += mss = 4000 + +Previously we would find the new_len > skb->len check failing, so we +would fall through and set pkt_len = new_len = 4000 and chop off +pkt_len of 4000 from the 4000-byte skb, leaving a 0-byte segment +afterward in the write queue. + +With this new commit, we notice that the new new_len >= skb->len check +succeeds, so that we return without trying to fragment. + +Fixes: adb92db857ee ("tcp: Make SACK code to split only at mss boundaries") +Reported-by: Eric Dumazet +Signed-off-by: Neal Cardwell +Cc: Eric Dumazet +Cc: Yuchung Cheng +Cc: Ilpo Jarvinen +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_input.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -1304,7 +1304,7 @@ static int tcp_match_skb_to_sack(struct + unsigned int new_len = (pkt_len / mss) * mss; + if (!in_sack && new_len < pkt_len) { + new_len += mss; +- if (new_len > skb->len) ++ if (new_len >= skb->len) + return 0; + } + pkt_len = new_len; diff --git a/queue-3.4/tipc-clear-next-pointer-of-message-fragments-before-reassembly.patch b/queue-3.4/tipc-clear-next-pointer-of-message-fragments-before-reassembly.patch new file mode 100644 index 00000000000..822af6ea498 --- /dev/null +++ b/queue-3.4/tipc-clear-next-pointer-of-message-fragments-before-reassembly.patch @@ -0,0 +1,41 @@ +From foo@baz Sat Jul 26 10:02:43 PDT 2014 +From: Jon Paul Maloy +Date: Fri, 11 Jul 2014 08:45:27 -0400 +Subject: tipc: clear 'next'-pointer of message fragments before reassembly + +From: Jon Paul Maloy + +[ Upstream commit 999417549c16dd0e3a382aa9f6ae61688db03181 ] + +If the 'next' pointer of the last fragment buffer in a message is not +zeroed before reassembly, we risk ending up with a corrupt message, +since the reassembly function itself isn't doing this. + +Currently, when a buffer is retrieved from the deferred queue of the +broadcast link, the next pointer is not cleared, with the result as +described above. + +This commit corrects this, and thereby fixes a bug that may occur when +long broadcast messages are transmitted across dual interfaces. The bug +has been present since 40ba3cdf542a469aaa9083fa041656e59b109b90 ("tipc: +message reassembly using fragment chain") + +This commit should be applied to both net and net-next. + +Signed-off-by: Jon Maloy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/bcast.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/tipc/bcast.c ++++ b/net/tipc/bcast.c +@@ -541,6 +541,7 @@ receive: + + buf = node->bclink.deferred_head; + node->bclink.deferred_head = buf->next; ++ buf->next = NULL; + node->bclink.deferred_size--; + goto receive; + } -- 2.47.3