[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251121015933.3618528-1-maze@google.com>
Date: Thu, 20 Nov 2025 17:59:33 -0800
From: "Maciej Żenczykowski" <maze@...gle.com>
To: "Maciej Żenczykowski" <zenczykowski@...il.com>
Cc: Linux Network Development Mailing List <netdev@...r.kernel.org>, "David S . Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>, Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>,
"Maciej Żenczykowski" <maze@...gle.com>, Lorenzo Colitti <lorenzo@...gle.com>,
Neal Cardwell <ncardwell@...gle.com>, bpf@...r.kernel.org
Subject: [PATCH net] net: fix propagation of EPERM from tcp_connect()
bpf CGROUP_INET_EGRESS hook can fail packet transmit resulting
in -EPERM, however as this is not -ECONNREFUSED it results in tcp
simply treating it as a lost packet resulting in a need to wait
for retransmits and timeout before an error is signaled back
to userspace.
Android implements a lot of security/power savings policy
in this hook, so these failures are common and more or less
permanent (at least until something significant happens).
We cannot currently call bpf_set_retval() from that hook point
and while this could be trivially fixed with a one line deletion,
it's not clear if that's truly a good idea (would we want to
be able to set arbitrary error values??).
If the hook *truly* wants to drop the packet without signaling
an error, it should IMHO return '2' for congestion caused drop
instead of '0' for drop.
Another possibility would be to teach the hook to treat (a new)
return value of '4' as meaning 'drop and return ECONNREFUSED',
but this seems easier... furthermore EPERM seems like a better
return to userspace for 'policy denied your transmit', while
ECONNREFUSED seems to suggest the remote server refused it.
Cc: Lorenzo Colitti <lorenzo@...gle.com>
Cc: Neal Cardwell <ncardwell@...gle.com>
Cc: Eric Dumazet <edumazet@...gle.com>
Cc: bpf@...r.kernel.org
Signed-off-by: Maciej Żenczykowski <maze@...gle.com>
---
net/ipv4/tcp_output.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 479afb714bdf..3ab21249e196 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -4336,7 +4336,7 @@ int tcp_connect(struct sock *sk)
/* Send off SYN; include data in Fast Open. */
err = tp->fastopen_req ? tcp_send_syn_data(sk, buff) :
tcp_transmit_skb(sk, buff, 1, sk->sk_allocation);
- if (err == -ECONNREFUSED)
+ if (err == -ECONNREFUSED || err == -EPERM)
return err;
/* We change tp->snd_nxt after the tcp_transmit_skb() call
--
2.52.0.rc2.455.g230fcf2819-goog
Powered by blists - more mailing lists