mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
tcp: do not let tcp_collapse() drive sk_forward_alloc negative
tcp_collapse() charges each newly allocated skb with skb_set_owner_r()
before the skbs it replaces are freed, without scheduling memory first.
Since sk_mem_uncharge() reclaims eagerly, sk->sk_forward_alloc has no
cushion and can become negative. This can be durable when the collapsed
skbs had a high payload/truesize ratio or were partially read, because
the new skbs can have a bigger total truesize than the old ones.
A negative sk_forward_alloc then confuses tcp_wmem_schedule(), which
can return a negative length to tcp_sendmsg_locked(), triggering
a WARN_ON_ONCE(bytes > INT_MAX) in check_copy_size().
Call sk_forced_mem_schedule() before charging nskb.
Fixes: 4890b686f4 ("net: keep sk->sk_forward_alloc as small as possible")
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Signed-off-by: Octavian Purdila <tavip@google.com>
Signed-off-by: Dave Miller <davem@davem-thinkpadp1gen8.ibmlond.csb>
This commit is contained in:
parent
23fec4bd76
commit
031c403d13
|
|
@ -5878,6 +5878,10 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, struct rb_root *root,
|
|||
__skb_queue_before(list, skb, nskb);
|
||||
else
|
||||
__skb_queue_tail(&tmp, nskb); /* defer rbtree insertion */
|
||||
/* nskb is charged before the skbs it replaces are freed.
|
||||
* Make sure sk->sk_forward_alloc can not become negative.
|
||||
*/
|
||||
sk_forced_mem_schedule(sk, nskb->truesize);
|
||||
skb_set_owner_r(nskb, sk);
|
||||
mptcp_skb_ext_move(nskb, skb);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user