]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 26 Jul 2014 17:03:39 +0000 (10:03 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 26 Jul 2014 17:03:39 +0000 (10:03 -0700)
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

14 files changed:
queue-3.4/8021q-fix-a-potential-memory-leak.patch [new file with mode: 0644]
queue-3.4/appletalk-fix-socket-referencing-in-skb.patch [new file with mode: 0644]
queue-3.4/be2net-set-eq-db-clear-intr-bit-in-be_open.patch [new file with mode: 0644]
queue-3.4/dns_resolver-assure-that-dns_query-result-is-null-terminated.patch [new file with mode: 0644]
queue-3.4/dns_resolver-null-terminate-the-right-string.patch [new file with mode: 0644]
queue-3.4/igmp-fix-the-problem-when-mc-leave-group.patch [new file with mode: 0644]
queue-3.4/ipv4-fix-buffer-overflow-in-ip_options_compile.patch [new file with mode: 0644]
queue-3.4/net-pppoe-use-correct-channel-mtu-when-using-multilink-ppp.patch [new file with mode: 0644]
queue-3.4/net-sctp-fix-information-leaks-in-ulpevent-layer.patch [new file with mode: 0644]
queue-3.4/series
queue-3.4/sunvnet-clean-up-objects-created-in-vnet_new-on-vnet_exit.patch [new file with mode: 0644]
queue-3.4/tcp-fix-false-undo-corner-cases.patch [new file with mode: 0644]
queue-3.4/tcp-fix-tcp_match_skb_to_sack-for-unaligned-sack-at-end-of-an-skb.patch [new file with mode: 0644]
queue-3.4/tipc-clear-next-pointer-of-message-fragments-before-reassembly.patch [new file with mode: 0644]

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 (file)
index 0000000..357a2e1
--- /dev/null
@@ -0,0 +1,36 @@
+From foo@baz Sat Jul 26 10:02:43 PDT 2014
+From: Li RongQing <roy.qing.li@gmail.com>
+Date: Wed, 18 Jun 2014 13:46:02 +0800
+Subject: 8021q: fix a potential memory leak
+
+From: Li RongQing <roy.qing.li@gmail.com>
+
+[ 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 <roy.qing.li@gmail.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..f1264c7
--- /dev/null
@@ -0,0 +1,44 @@
+From foo@baz Sat Jul 26 10:02:43 PDT 2014
+From: Andrey Utkin <andrey.krieger.utkin@gmail.com>
+Date: Mon, 7 Jul 2014 23:22:50 +0300
+Subject: appletalk: Fix socket referencing in skb
+
+From: Andrey Utkin <andrey.krieger.utkin@gmail.com>
+
+[ 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 <eric.dumazet@gmail.com> for correct solution.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=79441
+Reported-by: Ed Martin <edman007@edman007.com>
+Signed-off-by: Andrey Utkin <andrey.krieger.utkin@gmail.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..f3e8c58
--- /dev/null
@@ -0,0 +1,34 @@
+From foo@baz Sat Jul 26 10:02:43 PDT 2014
+From: Suresh Reddy <Suresh.Reddy@emulex.com>
+Date: Fri, 11 Jul 2014 14:03:01 +0530
+Subject: be2net: set EQ DB clear-intr bit in be_open()
+
+From: Suresh Reddy <Suresh.Reddy@emulex.com>
+
+[ 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 <Suresh.Reddy@emulex.com>
+Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..082aa42
--- /dev/null
@@ -0,0 +1,35 @@
+From foo@baz Sat Jul 26 10:02:43 PDT 2014
+From: =?UTF-8?q?Manuel=20Sch=C3=B6lling?= <manuel.schoelling@gmx.de>
+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?= <manuel.schoelling@gmx.de>
+
+[ 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 <manuel.schoelling@gmx.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..171d0b5
--- /dev/null
@@ -0,0 +1,31 @@
+From foo@baz Sat Jul 26 10:02:43 PDT 2014
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Mon, 21 Jul 2014 00:06:48 +0100
+Subject: dns_resolver: Null-terminate the right string
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+[ 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 <ben@decadent.org.uk>
+Fixes: 84a7c0b1db1c ("dns_resolver: assure that dns_query() result is null-terminated")
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..add8e2c
--- /dev/null
@@ -0,0 +1,84 @@
+From foo@baz Sat Jul 26 10:02:43 PDT 2014
+From: dingtianhong <dingtianhong@huawei.com>
+Date: Wed, 2 Jul 2014 13:50:48 +0800
+Subject: igmp: fix the problem when mc leave group
+
+From: dingtianhong <dingtianhong@huawei.com>
+
+[ 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 <dingtianhong@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..88769de
--- /dev/null
@@ -0,0 +1,82 @@
+From foo@baz Sat Jul 26 10:02:43 PDT 2014
+From: Eric Dumazet <edumazet@google.com>
+Date: Mon, 21 Jul 2014 07:17:42 +0200
+Subject: ipv4: fix buffer overflow in ip_options_compile()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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]  [<ffffffff81802f91>] ip_options_compile+0x121/0x9c0
+[28504.915394]  [<ffffffff81804a0d>] ip_options_get_from_user+0xad/0x120
+[28504.916843]  [<ffffffff8180dedf>] do_ip_setsockopt.isra.15+0x8df/0x1630
+[28504.918175]  [<ffffffff8180ec60>] ip_setsockopt+0x30/0xa0
+[28504.919490]  [<ffffffff8181e59b>] tcp_setsockopt+0x5b/0x90
+[28504.920835]  [<ffffffff8177462f>] sock_common_setsockopt+0x5f/0x70
+[28504.922208]  [<ffffffff817729c2>] SyS_setsockopt+0xa2/0x140
+[28504.923459]  [<ffffffff818cfb69>] system_call_fastpath+0x16/0x1b
+[28504.924722]
+[28504.925106] Allocated by thread T15843:
+[28504.925815]  [<ffffffff81804995>] ip_options_get_from_user+0x35/0x120
+[28504.926884]  [<ffffffff8180dedf>] do_ip_setsockopt.isra.15+0x8df/0x1630
+[28504.927975]  [<ffffffff8180ec60>] ip_setsockopt+0x30/0xa0
+[28504.929175]  [<ffffffff8181e59b>] tcp_setsockopt+0x5b/0x90
+[28504.930400]  [<ffffffff8177462f>] sock_common_setsockopt+0x5f/0x70
+[28504.931677]  [<ffffffff817729c2>] SyS_setsockopt+0xa2/0x140
+[28504.932851]  [<ffffffff818cfb69>] 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 <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..5f310dd
--- /dev/null
@@ -0,0 +1,129 @@
+From foo@baz Sat Jul 26 10:02:43 PDT 2014
+From: Christoph Schulz <develop@kristov.de>
+Date: Sun, 13 Jul 2014 00:53:15 +0200
+Subject: net: pppoe: use correct channel MTU when using Multilink PPP
+
+From: Christoph Schulz <develop@kristov.de>
+
+[ 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 <develop@kristov.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..3a55bb0
--- /dev/null
@@ -0,0 +1,256 @@
+From foo@baz Sat Jul 26 10:02:43 PDT 2014
+From: Daniel Borkmann <dborkman@redhat.com>
+Date: Sat, 12 Jul 2014 20:30:35 +0200
+Subject: net: sctp: fix information leaks in ulpevent layer
+
+From: Daniel Borkmann <dborkman@redhat.com>
+
+[ 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 <dborkman@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
index 28c02c9e0449b9057eafd16635653163349be0aa..68986d66514b1d04855b27abe51795de9fb368e5 100644 (file)
@@ -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 (file)
index 0000000..dcd71be
--- /dev/null
@@ -0,0 +1,69 @@
+From foo@baz Sat Jul 26 10:02:43 PDT 2014
+From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+Date: Wed, 16 Jul 2014 10:02:26 -0400
+Subject: sunvnet: clean up objects created in vnet_new() on vnet_exit()
+
+From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+
+[ 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 <sowmini.varadhan@oracle.com>
+Acked-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Reviewed-by: Karl Volz <karl.volz@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..a358e8e
--- /dev/null
@@ -0,0 +1,96 @@
+From foo@baz Sat Jul 26 10:02:43 PDT 2014
+From: Yuchung Cheng <ycheng@google.com>
+Date: Wed, 2 Jul 2014 12:07:16 -0700
+Subject: tcp: fix false undo corner cases
+
+From: Yuchung Cheng <ycheng@google.com>
+
+[ 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 <ycheng@google.com>
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..f56a4f2
--- /dev/null
@@ -0,0 +1,65 @@
+From foo@baz Sat Jul 26 10:02:43 PDT 2014
+From: Neal Cardwell <ncardwell@google.com>
+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 <ncardwell@google.com>
+
+[ 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 <edumazet@google.com>
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: Yuchung Cheng <ycheng@google.com>
+Cc: Ilpo Jarvinen <ilpo.jarvinen@helsinki.fi>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..822af6e
--- /dev/null
@@ -0,0 +1,41 @@
+From foo@baz Sat Jul 26 10:02:43 PDT 2014
+From: Jon Paul Maloy <jon.maloy@ericsson.com>
+Date: Fri, 11 Jul 2014 08:45:27 -0400
+Subject: tipc: clear 'next'-pointer of message fragments before reassembly
+
+From: Jon Paul Maloy <jon.maloy@ericsson.com>
+
+[ 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 <jon.maloy@ericsson.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+       }