Patch "tcp: do not underestimate skb->truesize in tcp_trim_head()" has been added to the 3.18-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
tcp: do not underestimate skb->truesize in tcp_trim_head()
to the 3.18-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-do-not-underestimate-skb-truesize-in-tcp_trim_head.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Thu May 11 12:52:00 CEST 2017
From: Eric Dumazet <[email protected]>
Date: Wed, 26 Apr 2017 17:15:40 -0700
Subject: tcp: do not underestimate skb->truesize in tcp_trim_head()
From: Eric Dumazet <[email protected]>
[ Upstream commit 7162fb242cb8322beb558828fd26b33c3e9fc805 ]
Andrey found a way to trigger the WARN_ON_ONCE(delta < len) in skb_try_coalesce() using syzkaller and a filter attached to a TCP socket over loopback interface.
I believe one issue with looped skbs is that tcp_trim_head() can end up producing skb with under estimated truesize.
It hardly matters for normal conditions, since packets sent over loopback are never truncated.
Bytes trimmed from skb->head should not change skb truesize, since skb->head is not reallocated.
--- net/ipv4/tcp_output.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
net/ipv4/tcp_output.c +12 -7
@@ -1212,7 +1212,7 @@ int tcp_fragment(struct sock *sk, struct* eventually). The difference is that pulled data not copied, but * immediately discarded. */ -static void __pskb_trim_head (struct sk_buff *skb,int len) +static int __pskb_trim_head (struct sk_buff *skb,int len) {struct skb_shared_info *shinfo;int i, k, eat;
@@ -1222,7 +1222,7 @@ static void __pskb_trim_head(struct sk_b__skb_pull (skb, eat); len -= eat;if (!len) -return ; +return 0 ; } eat = len; k =0 ;
@@ -1248,23 +1248,28 @@ static void __pskb_trim_head(struct sk_bskb_reset_tail_pointer (skb); skb->data_len -= len; skb->len = skb->data_len; +return len; }/* Remove acked data from a packet in the transmit queue. */ int tcp_trim_head (struct sock *sk,struct sk_buff *skb,u32 len) { +u32 delta_truesize; +if (skb_unclone (skb,GFP_ATOMIC ))return -ENOMEM ; -__pskb_trim_head (skb, len); + delta_truesize =__pskb_trim_head (skb, len);TCP_SKB_CB (skb)->seq += len; skb->ip_summed =CHECKSUM_PARTIAL ; - skb->truesize -= len; - sk->sk_wmem_queued -= len; -sk_mem_uncharge (sk, len); -sock_set_flag (sk,SOCK_QUEUE_SHRUNK ); +if (delta_truesize) { + skb->truesize -= delta_truesize; + sk->sk_wmem_queued -= delta_truesize; +sk_mem_uncharge (sk, delta_truesize); +sock_set_flag (sk,SOCK_QUEUE_SHRUNK ); + }/* Any change of skb->len requires recalculation of tso factor. */ if (tcp_skb_pcount (skb) >1 )
Patches currently in stable-queue which might be from [email protected] are
queue-3.18/tcp-do-not-underestimate-skb-truesize-in-tcp_trim_head.patch queue-3.18/tcp-fix-wraparound-issue-in-tcp_lp.patch