Skip to content

Commit a3daac6

Browse files
committed
Merge branch 'tcp-tcp-challenge-ack-fixes'
Eric Dumazet says: ==================== tcp: tcp challenge ack fixes syzbot found a typical data-race addressed in the first patch. While we are at it, second patch makes the global rate limit per net-ns and disabled by default. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 52267ce + 79e3602 commit a3daac6

File tree

4 files changed

+21
-13
lines changed

4 files changed

+21
-13
lines changed

Documentation/networking/ip-sysctl.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,10 @@ tcp_limit_output_bytes - INTEGER
10351035
tcp_challenge_ack_limit - INTEGER
10361036
Limits number of Challenge ACK sent per second, as recommended
10371037
in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks)
1038-
Default: 1000
1038+
Note that this per netns rate limit can allow some side channel
1039+
attacks and probably should not be enabled.
1040+
TCP stack implements per TCP socket limits anyway.
1041+
Default: INT_MAX (unlimited)
10391042

10401043
UDP variables
10411044
=============

include/net/netns/ipv4.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ struct netns_ipv4 {
179179
unsigned int sysctl_tcp_fastopen_blackhole_timeout;
180180
atomic_t tfo_active_disable_times;
181181
unsigned long tfo_active_disable_stamp;
182+
u32 tcp_challenge_timestamp;
183+
u32 tcp_challenge_count;
182184

183185
int sysctl_udp_wmem_min;
184186
int sysctl_udp_rmem_min;

net/ipv4/tcp_input.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3614,31 +3614,32 @@ bool tcp_oow_rate_limited(struct net *net, const struct sk_buff *skb,
36143614
/* RFC 5961 7 [ACK Throttling] */
36153615
static void tcp_send_challenge_ack(struct sock *sk)
36163616
{
3617-
/* unprotected vars, we dont care of overwrites */
3618-
static u32 challenge_timestamp;
3619-
static unsigned int challenge_count;
36203617
struct tcp_sock *tp = tcp_sk(sk);
36213618
struct net *net = sock_net(sk);
3622-
u32 count, now;
3619+
u32 count, now, ack_limit;
36233620

36243621
/* First check our per-socket dupack rate limit. */
36253622
if (__tcp_oow_rate_limited(net,
36263623
LINUX_MIB_TCPACKSKIPPEDCHALLENGE,
36273624
&tp->last_oow_ack_time))
36283625
return;
36293626

3627+
ack_limit = READ_ONCE(net->ipv4.sysctl_tcp_challenge_ack_limit);
3628+
if (ack_limit == INT_MAX)
3629+
goto send_ack;
3630+
36303631
/* Then check host-wide RFC 5961 rate limit. */
36313632
now = jiffies / HZ;
3632-
if (now != challenge_timestamp) {
3633-
u32 ack_limit = READ_ONCE(net->ipv4.sysctl_tcp_challenge_ack_limit);
3633+
if (now != READ_ONCE(net->ipv4.tcp_challenge_timestamp)) {
36343634
u32 half = (ack_limit + 1) >> 1;
36353635

3636-
challenge_timestamp = now;
3637-
WRITE_ONCE(challenge_count, half + prandom_u32_max(ack_limit));
3636+
WRITE_ONCE(net->ipv4.tcp_challenge_timestamp, now);
3637+
WRITE_ONCE(net->ipv4.tcp_challenge_count, half + prandom_u32_max(ack_limit));
36383638
}
3639-
count = READ_ONCE(challenge_count);
3639+
count = READ_ONCE(net->ipv4.tcp_challenge_count);
36403640
if (count > 0) {
3641-
WRITE_ONCE(challenge_count, count - 1);
3641+
WRITE_ONCE(net->ipv4.tcp_challenge_count, count - 1);
3642+
send_ack:
36423643
NET_INC_STATS(net, LINUX_MIB_TCPCHALLENGEACK);
36433644
tcp_send_ack(sk);
36443645
}

net/ipv4/tcp_ipv4.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3139,8 +3139,10 @@ static int __net_init tcp_sk_init(struct net *net)
31393139
net->ipv4.sysctl_tcp_tso_win_divisor = 3;
31403140
/* Default TSQ limit of 16 TSO segments */
31413141
net->ipv4.sysctl_tcp_limit_output_bytes = 16 * 65536;
3142-
/* rfc5961 challenge ack rate limiting */
3143-
net->ipv4.sysctl_tcp_challenge_ack_limit = 1000;
3142+
3143+
/* rfc5961 challenge ack rate limiting, per net-ns, disabled by default. */
3144+
net->ipv4.sysctl_tcp_challenge_ack_limit = INT_MAX;
3145+
31443146
net->ipv4.sysctl_tcp_min_tso_segs = 2;
31453147
net->ipv4.sysctl_tcp_tso_rtt_log = 9; /* 2^9 = 512 usec */
31463148
net->ipv4.sysctl_tcp_min_rtt_wlen = 300;

0 commit comments

Comments
 (0)