This is a note to let you know that I've just added the patch titled
tcp: must unclone packets before mangling them
to the 3.10-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
tcp-must-unclone-packets-before-mangling-them.patch
and it can be found in the queue-3.10 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.
>From 35536f38006d0995e3c14246c7b56f01e8f9f047 Mon Sep 17 00:00:00 2001
From: Eric Dumazet <[email protected]>
Date: Tue, 15 Oct 2013 11:54:30 -0700
Subject: tcp: must unclone packets before mangling them
From: Eric Dumazet <[email protected]>
[ Upstream commit c52e2421f7368fd36cbe330d2cf41b10452e39a9 ]
TCP stack should make sure it owns skbs before mangling them.
We had various crashes using bnx2x, and it turned out gso_size
was cleared right before bnx2x driver was populating TC descriptor
of the _previous_ packet send. TCP stack can sometime retransmit
packets that are still in Qdisc.
Of course we could make bnx2x driver more robust (using
ACCESS_ONCE(shinfo->gso_size) for example), but the bug is TCP stack.
We have identified two points where skb_unclone() was needed.
This patch adds a WARN_ON_ONCE() to warn us if we missed another
fix of this kind.
Kudos to Neal for finding the root cause of this bug. Its visible
using small MSS.
Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: Neal Cardwell <[email protected]>
Cc: Yuchung Cheng <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
net/ipv4/tcp_output.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -976,6 +976,9 @@ static void tcp_queue_skb(struct sock *s
static void tcp_set_skb_tso_segs(const struct sock *sk, struct sk_buff *skb,
unsigned int mss_now)
{
+ /* Make sure we own this skb before messing gso_size/gso_segs */
+ WARN_ON_ONCE(skb_cloned(skb));
+
if (skb->len <= mss_now || !sk_can_gso(sk) ||
skb->ip_summed == CHECKSUM_NONE) {
/* Avoid the costly divide in the normal
@@ -1057,9 +1060,7 @@ int tcp_fragment(struct sock *sk, struct
if (nsize < 0)
nsize = 0;
- if (skb_cloned(skb) &&
- skb_is_nonlinear(skb) &&
- pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+ if (skb_unclone(skb, GFP_ATOMIC))
return -ENOMEM;
/* Get a new skb... force flag on. */
@@ -2334,6 +2335,8 @@ int __tcp_retransmit_skb(struct sock *sk
int oldpcount = tcp_skb_pcount(skb);
if (unlikely(oldpcount > 1)) {
+ if (skb_unclone(skb, GFP_ATOMIC))
+ return -ENOMEM;
tcp_init_tso_segs(sk, skb, cur_mss);
tcp_adjust_pcount(sk, skb, oldpcount -
tcp_skb_pcount(skb));
}
Patches currently in stable-queue which might be from [email protected] are
queue-3.10/tcp-tsq-can-use-a-dynamic-limit.patch
queue-3.10/ipv4-fix-ineffective-source-address-selection.patch
queue-3.10/net-unix-inherit-sock_pass-cred-sec-flags-from-socket-to-fix-race.patch
queue-3.10/net-do-not-call-sock_put-on-timewait-sockets.patch
queue-3.10/tcp-must-unclone-packets-before-mangling-them.patch
queue-3.10/l2tp-must-disable-bh-before-calling-l2tp_xmit_skb.patch
queue-3.10/tcp-do-not-forget-fin-in-tcp_shifted_skb.patch
queue-3.10/bnx2x-record-rx-queue-for-lro-packets.patch
queue-3.10/tcp-tso-packets-automatic-sizing.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html