mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net] net: raw: fix ICMP unreachable sent when receive queue is full
@ 2026-11-04 11:57 Jiayuan Chen
  2026-11-10  2:54 ` patchwork-bot+netdevbpf
  0 siblings, 1 reply; 2+ messages in thread
From: Jiayuan Chen @ 2026-11-04 11:57 UTC (permalink / raw)
  To: netdev
  Cc: Jiayuan Chen, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Willem de Bruijn, Kees Cook,
	Jeff Layton, Runyu Xiao, Breno Leitao, Gustavo A. R. Silva,
	Joe Damato, Stanislav Fomichev, Li RongQing, linux-kernel

It's found in a raw socket application. When the application doesn't
read packets in time, the client receives ICMP Protocol Unreachable,
which makes the client abort the session.

The reason is that the server hits the sk_rcvbuf limit, and
raw_v4_input() skips the socket before setting 'delivered', so it
returns 0. Then ip_protocol_deliver_rcu() sees 'raw' is 0, thinks no one
handles this protocol and calls icmp_send() to send ICMP Protocol
Unreachable.

IPv6 has the same issue, ip6_protocol_deliver_rcu() sends ICMPv6
Parameter Problem instead.

Also, we'd better run icmp_filter() and ip_mc_sf_allow() (icmpv6_filter()
for IPv6) before we check sk_rcvbuf, otherwise packets rejected by
ICMP_FILTER/ICMPV6_FILTER or the multicast filter are counted in
sk_drops. So move the check right before skb_clone().

Fixes: d721812aa875 ("ipv4: raw: check sk->sk_rcvbuf earlier")
Fixes: 026763ece881 ("ipv6: raw: check sk->sk_rcvbuf earlier")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
---
 net/ipv4/raw.c | 15 ++++++++-------
 net/ipv6/raw.c | 15 ++++++++-------
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 9d01006d8189..f33a9dfc5309 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -182,18 +182,19 @@ static int raw_v4_input(struct net *net, struct sk_buff *skb,
 				  iph->saddr, iph->daddr, dif, sdif))
 			continue;
 
-		if (atomic_read(&sk->sk_rmem_alloc) >=
-		    READ_ONCE(sk->sk_rcvbuf)) {
-			sk_drops_inc(sk);
-			continue;
-		}
-
 		delivered = 1;
 		if ((iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) &&
 		    ip_mc_sf_allow(sk, iph->daddr, iph->saddr,
 				   skb->dev->ifindex, sdif)) {
-			struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
+			struct sk_buff *clone;
+
+			if (atomic_read(&sk->sk_rmem_alloc) >=
+			    READ_ONCE(sk->sk_rcvbuf)) {
+				sk_drops_inc(sk);
+				continue;
+			}
 
+			clone = skb_clone(skb, GFP_ATOMIC);
 			/* Not releasing hash table! */
 			if (clone)
 				raw_rcv(sk, clone);
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index b965258cf9e5..eb99f4a906ec 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -160,12 +160,6 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
 				  inet6_iif(skb), inet6_sdif(skb)))
 			continue;
 
-		if (atomic_read(&sk->sk_rmem_alloc) >=
-		    READ_ONCE(sk->sk_rcvbuf)) {
-			sk_drops_inc(sk);
-			continue;
-		}
-
 		delivered = true;
 		switch (nexthdr) {
 		case IPPROTO_ICMPV6:
@@ -197,8 +191,15 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
 		if (filtered < 0)
 			break;
 		if (filtered == 0) {
-			struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
+			struct sk_buff *clone;
+
+			if (atomic_read(&sk->sk_rmem_alloc) >=
+			    READ_ONCE(sk->sk_rcvbuf)) {
+				sk_drops_inc(sk);
+				continue;
+			}
 
+			clone = skb_clone(skb, GFP_ATOMIC);
 			/* Not releasing hash table! */
 			if (clone)
 				rawv6_rcv(sk, clone);
-- 
2.43.0


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

* Re: [PATCH net] net: raw: fix ICMP unreachable sent when receive queue is full
  2026-11-04 11:57 [PATCH net] net: raw: fix ICMP unreachable sent when receive queue is full Jiayuan Chen
@ 2026-11-10  2:54 ` patchwork-bot+netdevbpf
  0 siblings, 0 replies; 2+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-11-10  2:54 UTC (permalink / raw)
  To: Jiayuan Chen
  Cc: netdev, davem, edumazet, kuba, pabeni, horms, willemb, kees,
	jlayton, runyu.xiao, leitao, gustavoars, joe, sdf, lirongqing,
	linux-kernel

Hello:

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

On Wed,  4 Nov 2026 19:57:26 +0800 you wrote:
> It's found in a raw socket application. When the application doesn't
> read packets in time, the client receives ICMP Protocol Unreachable,
> which makes the client abort the session.
> 
> The reason is that the server hits the sk_rcvbuf limit, and
> raw_v4_input() skips the socket before setting 'delivered', so it
> returns 0. Then ip_protocol_deliver_rcu() sees 'raw' is 0, thinks no one
> handles this protocol and calls icmp_send() to send ICMP Protocol
> Unreachable.
> 
> [...]

Here is the summary with links:
  - [net] net: raw: fix ICMP unreachable sent when receive queue is full
    https://git.kernel.org/netdev/net/c/45441a94d502

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] 2+ messages in thread

end of thread, other threads:[~2026-11-10  2:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-04 11:57 [PATCH net] net: raw: fix ICMP unreachable sent when receive queue is full Jiayuan Chen
2026-11-10  2:54 ` 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

all inboxes | Powered by JetHome®