net: fix memory limit bug in tcp_fragment

upstream:
b6653b3629e5 ("tcp: refine memory limit test in tcp_fragment")
b617158dc096 ("tcp: be more careful in tcp_fragment")

tcp_fragment() might be called for skbs in the write queue.

Memory limits might have been exceeded because tcp_sendmsg() only
checks limits at full skb (64KB) boundaries.

Therefore, we need to make sure tcp_fragment() wont punish applications
that might have setup very low SO_SNDBUF values.

75c119afe14f ("tcp: implement rb-tree based retransmit queue")
separate transmit queue to transmit queue and retransmit queue.
b6653b36 adds some check to the transmit queue, b617158dc adds some check
on the rtx queue.

So we only backport the b6653b36 patch. use tcp_send_head(sk) instead of
TCP_FRAG_IN_WRITE_QUEUE.

Signed-off-by: Hongbo Li <herberthbli@tencent.com>
This commit is contained in:
Hongbo Li 2019-10-23 17:28:36 +08:00 committed by Xiaoming Gao
parent 41a3398393
commit ef9d6889ab
1 changed files with 2 additions and 1 deletions

View File

@ -1270,7 +1270,8 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
if (nsize < 0)
nsize = 0;
if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf)) {
if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf &&
skb != tcp_send_head(sk))) {
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG);
return -ENOMEM;
}