netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net 0/2] tcp: tcp challenge ack fixes
@ 2022-08-30 18:56 Eric Dumazet
  2022-08-30 18:56 ` [PATCH net 1/2] tcp: annotate data-race around challenge_timestamp Eric Dumazet
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Eric Dumazet @ 2022-08-30 18:56 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: netdev, Neal Cardwell, Jason Baron, Eric Dumazet, Eric Dumazet

From: Eric Dumazet <edumazet@google.com>

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.

Eric Dumazet (2):
  tcp: annotate data-race around challenge_timestamp
  tcp: make global challenge ack rate limitation per net-ns and default
    disabled

 Documentation/networking/ip-sysctl.rst |  5 ++++-
 include/net/netns/ipv4.h               |  2 ++
 net/ipv4/tcp_input.c                   | 21 +++++++++++----------
 net/ipv4/tcp_ipv4.c                    |  6 ++++--
 4 files changed, 21 insertions(+), 13 deletions(-)

-- 
2.37.2.672.g94769d06f0-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH net 1/2] tcp: annotate data-race around challenge_timestamp
  2022-08-30 18:56 [PATCH net 0/2] tcp: tcp challenge ack fixes Eric Dumazet
@ 2022-08-30 18:56 ` Eric Dumazet
  2022-08-31 12:55   ` Neal Cardwell
  2022-08-30 18:56 ` [PATCH net 2/2] tcp: make global challenge ack rate limitation per net-ns and default disabled Eric Dumazet
  2022-09-01  4:00 ` [PATCH net 0/2] tcp: tcp challenge ack fixes patchwork-bot+netdevbpf
  2 siblings, 1 reply; 6+ messages in thread
From: Eric Dumazet @ 2022-08-30 18:56 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: netdev, Neal Cardwell, Jason Baron, Eric Dumazet, Eric Dumazet, syzbot

From: Eric Dumazet <edumazet@google.com>

challenge_timestamp can be read an written by concurrent threads.

This was expected, but we need to annotate the race to avoid potential issues.

Following patch moves challenge_timestamp and challenge_count
to per-netns storage to provide better isolation.

Fixes: 354e4aa391ed ("tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation")
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 net/ipv4/tcp_input.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index ab5f0ea166f1a0535e299a9051406b5e2895f1f0..c184e15397a28ccfbac142ff0f1d05d555623147 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3629,11 +3629,11 @@ static void tcp_send_challenge_ack(struct sock *sk)
 
 	/* Then check host-wide RFC 5961 rate limit. */
 	now = jiffies / HZ;
-	if (now != challenge_timestamp) {
+	if (now != READ_ONCE(challenge_timestamp)) {
 		u32 ack_limit = READ_ONCE(net->ipv4.sysctl_tcp_challenge_ack_limit);
 		u32 half = (ack_limit + 1) >> 1;
 
-		challenge_timestamp = now;
+		WRITE_ONCE(challenge_timestamp, now);
 		WRITE_ONCE(challenge_count, half + prandom_u32_max(ack_limit));
 	}
 	count = READ_ONCE(challenge_count);
-- 
2.37.2.672.g94769d06f0-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH net 2/2] tcp: make global challenge ack rate limitation per net-ns and default disabled
  2022-08-30 18:56 [PATCH net 0/2] tcp: tcp challenge ack fixes Eric Dumazet
  2022-08-30 18:56 ` [PATCH net 1/2] tcp: annotate data-race around challenge_timestamp Eric Dumazet
@ 2022-08-30 18:56 ` Eric Dumazet
  2022-08-31 12:59   ` Neal Cardwell
  2022-09-01  4:00 ` [PATCH net 0/2] tcp: tcp challenge ack fixes patchwork-bot+netdevbpf
  2 siblings, 1 reply; 6+ messages in thread
From: Eric Dumazet @ 2022-08-30 18:56 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: netdev, Neal Cardwell, Jason Baron, Eric Dumazet, Eric Dumazet

From: Eric Dumazet <edumazet@google.com>

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:

083ae308280d ("tcp: enable per-socket rate limiting of all 'challenge acks'")
f2b2c582e824 ("tcp: mitigate ACK loops for connections as tcp_sock")
75ff39ccc1bd ("tcp: make challenge acks less predictable")

Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Jason Baron <jbaron@akamai.com>
Cc: Neal Cardwell <ncardwell@google.com>
---
 Documentation/networking/ip-sysctl.rst |  5 ++++-
 include/net/netns/ipv4.h               |  2 ++
 net/ipv4/tcp_input.c                   | 21 +++++++++++----------
 net/ipv4/tcp_ipv4.c                    |  6 ++++--
 4 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
index 56cd4ea059b2a33cde01d8db598b160762db1478..a759872a2883bbce925833007a540f06c68a9442 100644
--- a/Documentation/networking/ip-sysctl.rst
+++ b/Documentation/networking/ip-sysctl.rst
@@ -1035,7 +1035,10 @@ tcp_limit_output_bytes - INTEGER
 tcp_challenge_ack_limit - INTEGER
 	Limits number of Challenge ACK sent per second, as recommended
 	in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks)
-	Default: 1000
+	Note that this per netns rate limit can allow some side channel
+	attacks and probably should not be enabled.
+	TCP stack implements per TCP socket limits anyway.
+	Default: INT_MAX (unlimited)
 
 UDP variables
 =============
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index c7320ef356d940aefba708ea98de502253d2b04d..6320a76cefdcdf6232b7a94ddd0c4a433084887d 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -179,6 +179,8 @@ struct netns_ipv4 {
 	unsigned int sysctl_tcp_fastopen_blackhole_timeout;
 	atomic_t tfo_active_disable_times;
 	unsigned long tfo_active_disable_stamp;
+	u32 tcp_challenge_timestamp;
+	u32 tcp_challenge_count;
 
 	int sysctl_udp_wmem_min;
 	int sysctl_udp_rmem_min;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index c184e15397a28ccfbac142ff0f1d05d555623147..b85a9f755da41505b35bc64e1fa8995581660e90 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3614,12 +3614,9 @@ bool tcp_oow_rate_limited(struct net *net, const struct sk_buff *skb,
 /* RFC 5961 7 [ACK Throttling] */
 static void tcp_send_challenge_ack(struct sock *sk)
 {
-	/* unprotected vars, we dont care of overwrites */
-	static u32 challenge_timestamp;
-	static unsigned int challenge_count;
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct net *net = sock_net(sk);
-	u32 count, now;
+	u32 count, now, ack_limit;
 
 	/* First check our per-socket dupack rate limit. */
 	if (__tcp_oow_rate_limited(net,
@@ -3627,18 +3624,22 @@ static void tcp_send_challenge_ack(struct sock *sk)
 				   &tp->last_oow_ack_time))
 		return;
 
+	ack_limit = READ_ONCE(net->ipv4.sysctl_tcp_challenge_ack_limit);
+	if (ack_limit == INT_MAX)
+		goto send_ack;
+
 	/* Then check host-wide RFC 5961 rate limit. */
 	now = jiffies / HZ;
-	if (now != READ_ONCE(challenge_timestamp)) {
-		u32 ack_limit = READ_ONCE(net->ipv4.sysctl_tcp_challenge_ack_limit);
+	if (now != READ_ONCE(net->ipv4.tcp_challenge_timestamp)) {
 		u32 half = (ack_limit + 1) >> 1;
 
-		WRITE_ONCE(challenge_timestamp, now);
-		WRITE_ONCE(challenge_count, half + prandom_u32_max(ack_limit));
+		WRITE_ONCE(net->ipv4.tcp_challenge_timestamp, now);
+		WRITE_ONCE(net->ipv4.tcp_challenge_count, half + prandom_u32_max(ack_limit));
 	}
-	count = READ_ONCE(challenge_count);
+	count = READ_ONCE(net->ipv4.tcp_challenge_count);
 	if (count > 0) {
-		WRITE_ONCE(challenge_count, count - 1);
+		WRITE_ONCE(net->ipv4.tcp_challenge_count, count - 1);
+send_ack:
 		NET_INC_STATS(net, LINUX_MIB_TCPCHALLENGEACK);
 		tcp_send_ack(sk);
 	}
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 0c83780dc9bf4293135b8044daf41090b66f8b08..5b019ba2b9d2155b6d612727d32c89433d19be03 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -3139,8 +3139,10 @@ static int __net_init tcp_sk_init(struct net *net)
 	net->ipv4.sysctl_tcp_tso_win_divisor = 3;
 	/* Default TSQ limit of 16 TSO segments */
 	net->ipv4.sysctl_tcp_limit_output_bytes = 16 * 65536;
-	/* rfc5961 challenge ack rate limiting */
-	net->ipv4.sysctl_tcp_challenge_ack_limit = 1000;
+
+	/* rfc5961 challenge ack rate limiting, per net-ns, disabled by default. */
+	net->ipv4.sysctl_tcp_challenge_ack_limit = INT_MAX;
+
 	net->ipv4.sysctl_tcp_min_tso_segs = 2;
 	net->ipv4.sysctl_tcp_tso_rtt_log = 9;  /* 2^9 = 512 usec */
 	net->ipv4.sysctl_tcp_min_rtt_wlen = 300;
-- 
2.37.2.672.g94769d06f0-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH net 1/2] tcp: annotate data-race around challenge_timestamp
  2022-08-30 18:56 ` [PATCH net 1/2] tcp: annotate data-race around challenge_timestamp Eric Dumazet
@ 2022-08-31 12:55   ` Neal Cardwell
  0 siblings, 0 replies; 6+ messages in thread
From: Neal Cardwell @ 2022-08-31 12:55 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, netdev,
	Jason Baron, Eric Dumazet, syzbot

On Tue, Aug 30, 2022 at 2:57 PM Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> From: Eric Dumazet <edumazet@google.com>
>
> challenge_timestamp can be read an written by concurrent threads.
>
> This was expected, but we need to annotate the race to avoid potential issues.
>
> Following patch moves challenge_timestamp and challenge_count
> to per-netns storage to provide better isolation.
>
> Fixes: 354e4aa391ed ("tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation")
> Reported-by: syzbot <syzkaller@googlegroups.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---

Acked-by: Neal Cardwell <ncardwell@google.com>

Thanks, Eric!

neal

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net 2/2] tcp: make global challenge ack rate limitation per net-ns and default disabled
  2022-08-30 18:56 ` [PATCH net 2/2] tcp: make global challenge ack rate limitation per net-ns and default disabled Eric Dumazet
@ 2022-08-31 12:59   ` Neal Cardwell
  0 siblings, 0 replies; 6+ messages in thread
From: Neal Cardwell @ 2022-08-31 12:59 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, netdev,
	Jason Baron, Eric Dumazet

On Tue, Aug 30, 2022 at 2:57 PM Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> From: Eric Dumazet <edumazet@google.com>
>
> 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:
>
> 083ae308280d ("tcp: enable per-socket rate limiting of all 'challenge acks'")
> f2b2c582e824 ("tcp: mitigate ACK loops for connections as tcp_sock")
> 75ff39ccc1bd ("tcp: make challenge acks less predictable")
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Jason Baron <jbaron@akamai.com>
> Cc: Neal Cardwell <ncardwell@google.com>
> ---

Acked-by: Neal Cardwell <ncardwell@google.com>

Looks great. Thanks, Eric!

neal

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net 0/2] tcp: tcp challenge ack fixes
  2022-08-30 18:56 [PATCH net 0/2] tcp: tcp challenge ack fixes Eric Dumazet
  2022-08-30 18:56 ` [PATCH net 1/2] tcp: annotate data-race around challenge_timestamp Eric Dumazet
  2022-08-30 18:56 ` [PATCH net 2/2] tcp: make global challenge ack rate limitation per net-ns and default disabled Eric Dumazet
@ 2022-09-01  4:00 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-09-01  4:00 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: davem, kuba, pabeni, netdev, ncardwell, jbaron, edumazet

Hello:

This series was applied to netdev/net.git (master)
by Jakub Kicinski <kuba@kernel.org>:

On Tue, 30 Aug 2022 11:56:54 -0700 you wrote:
> From: Eric Dumazet <edumazet@google.com>
> 
> 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.
> 
> [...]

Here is the summary with links:
  - [net,1/2] tcp: annotate data-race around challenge_timestamp
    https://git.kernel.org/netdev/net/c/8c70521238b7
  - [net,2/2] tcp: make global challenge ack rate limitation per net-ns and default disabled
    https://git.kernel.org/netdev/net/c/79e3602caa6f

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-09-01  4:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-30 18:56 [PATCH net 0/2] tcp: tcp challenge ack fixes Eric Dumazet
2022-08-30 18:56 ` [PATCH net 1/2] tcp: annotate data-race around challenge_timestamp Eric Dumazet
2022-08-31 12:55   ` Neal Cardwell
2022-08-30 18:56 ` [PATCH net 2/2] tcp: make global challenge ack rate limitation per net-ns and default disabled Eric Dumazet
2022-08-31 12:59   ` Neal Cardwell
2022-09-01  4:00 ` [PATCH net 0/2] tcp: tcp challenge ack fixes patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).