Skip to content

Commit f070ef2

Browse files
Eric Dumazetdavem330
Eric Dumazet
authored andcommitted
tcp: tcp_fragment() should apply sane memory limits
Jonathan Looney reported that a malicious peer can force a sender to fragment its retransmit queue into tiny skbs, inflating memory usage and/or overflow 32bit counters. TCP allows an application to queue up to sk_sndbuf bytes, so we need to give some allowance for non malicious splitting of retransmit queue. A new SNMP counter is added to monitor how many times TCP did not allow to split an skb if the allowance was exceeded. Note that this counter might increase in the case applications use SO_SNDBUF socket option to lower sk_sndbuf. CVE-2019-11478 : tcp_fragment, prevent fragmenting a packet when the socket is already using more than half the allowed space Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: Jonathan Looney <jtl@netflix.com> Acked-by: Neal Cardwell <ncardwell@google.com> Acked-by: Yuchung Cheng <ycheng@google.com> Reviewed-by: Tyler Hicks <tyhicks@canonical.com> Cc: Bruce Curtis <brucec@netflix.com> Cc: Jonathan Lemon <jonathan.lemon@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 3b4929f commit f070ef2

File tree

3 files changed

+7
-0
lines changed

3 files changed

+7
-0
lines changed

include/uapi/linux/snmp.h

+1
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ enum
283283
LINUX_MIB_TCPACKCOMPRESSED, /* TCPAckCompressed */
284284
LINUX_MIB_TCPZEROWINDOWDROP, /* TCPZeroWindowDrop */
285285
LINUX_MIB_TCPRCVQDROP, /* TCPRcvQDrop */
286+
LINUX_MIB_TCPWQUEUETOOBIG, /* TCPWqueueTooBig */
286287
__LINUX_MIB_MAX
287288
};
288289

net/ipv4/proc.c

+1
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ static const struct snmp_mib snmp4_net_list[] = {
287287
SNMP_MIB_ITEM("TCPAckCompressed", LINUX_MIB_TCPACKCOMPRESSED),
288288
SNMP_MIB_ITEM("TCPZeroWindowDrop", LINUX_MIB_TCPZEROWINDOWDROP),
289289
SNMP_MIB_ITEM("TCPRcvQDrop", LINUX_MIB_TCPRCVQDROP),
290+
SNMP_MIB_ITEM("TCPWqueueTooBig", LINUX_MIB_TCPWQUEUETOOBIG),
290291
SNMP_MIB_SENTINEL
291292
};
292293

net/ipv4/tcp_output.c

+5
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,11 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue,
12961296
if (nsize < 0)
12971297
nsize = 0;
12981298

1299+
if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf)) {
1300+
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG);
1301+
return -ENOMEM;
1302+
}
1303+
12991304
if (skb_unclone(skb, gfp))
13001305
return -ENOMEM;
13011306

0 commit comments

Comments
 (0)