Skip to content

Commit 79e3602

Browse files
edumazetkuba-moo
authored andcommitted
tcp: make global challenge ack rate limitation per net-ns and default disabled
Because per host rate limiting has been proven problematic (side channel attacks can be based on it), per host rate limiting of challenge acks ideally should be per netns and turned off by default. This is a long due followup of following commits: 083ae30 ("tcp: enable per-socket rate limiting of all 'challenge acks'") f2b2c58 ("tcp: mitigate ACK loops for connections as tcp_sock") 75ff39c ("tcp: make challenge acks less predictable") Signed-off-by: Eric Dumazet <[email protected]> Cc: Jason Baron <[email protected]> Acked-by: Neal Cardwell <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 8c70521 commit 79e3602

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 != READ_ONCE(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-
WRITE_ONCE(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)