Netdev List
 help / color / mirror / Atom feed
* [PATCH] net/ipv6: icmp: fix is_ineligible() to block errors for Redirect packets
@ 2026-05-26 10:16 Sayooj K Karun
  2026-05-26 15:40 ` Alexander Lobakin
  2026-05-27  9:46 ` [PATCH v2 net] " Sayooj K Karun
  0 siblings, 2 replies; 7+ messages in thread
From: Sayooj K Karun @ 2026-05-26 10:16 UTC (permalink / raw)
  To: netdev
  Cc: dsahern, idosch, davem, edumazet, kuba, pabeni, horms,
	linux-kernel, Sayooj K Karun

RFC 4443 section 2.4(e.2) mandates that an ICMPv6 error message MUST NOT
be originated in response to an ICMPv6 Redirect message (type 137).

Add check for NDISC_REDIRECT (137) so that redirect packets become
ineligible and error packets are not generated for Redirect messages.

Signed-off-by: Sayooj K Karun <sayooj@aerlync.com>
---
 net/ipv6/icmp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index efb23807a026..3fdb3a97dd8e 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -157,7 +157,8 @@ static bool is_ineligible(const struct sk_buff *skb)
 		 */
 		if (!tp && frag_off != 0)
 			return false;
-		else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK))
+		else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK) ||
+			 *tp == NDISC_REDIRECT)
 			return true;
 	}
 	return false;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread
* [PATCH v2 net] net/ipv6: icmp: fix is_ineligible() to block errors for Redirect packets
@ 2026-05-27  9:50 Sayooj K Karun
  0 siblings, 0 replies; 7+ messages in thread
From: Sayooj K Karun @ 2026-05-27  9:50 UTC (permalink / raw)
  To: netdev
  Cc: dsahern, idosch, davem, edumazet, kuba, pabeni, horms,
	linux-kernel, aleksander.lobakin, Sayooj K Karun

Discovered while reading RFC 4443 and cross-checking the ICMPv6 stack,
which in section 2.4(e.2) mandates that an ICMPv6 error MUST NOT be
originated in response to an ICMPv6 Redirect message (type 137).

is_ineligible() is called by icmpv6_send() to decide whether a received
packet is eligible to trigger an ICMPv6 error. It uses
ICMPV6_INFOMSG_MASK (0x80) to suppress errors for ICMPv6 error types
(bit 7 clear) while passing informational types (bit 7 set). However,
NDISC_REDIRECT has type 137 (0x89), which has bit 7 set, so it passes
the mask check and is_ineligible() returns false and icmpv6_send()
proceeds to generate an error in response to a Redirect, violating the
RFC.

A triggerable scenario: a host with an ip6tables/nftables REJECT rule
applied to incoming ICMPv6 traffic (e.g., dropping Redirects from an
untrusted router). When the Redirect hits the REJECT rule,
nf_send_unreach6() calls icmpv6_send() with the Redirect as the
triggering skb. Without this fix, is_ineligible() returns false and a
Destination Unreachable is erroneously transmitted in response.

Add an explicit check for NDISC_REDIRECT so that Redirect packets are
treated as ineligible, suppressing ICMPv6 error generation in response
to them.

Signed-off-by: Sayooj K Karun <sayooj@aerlync.com>
---
The bug can be triggered via a netfilter REJECT rule targeting ICMPv6
Redirect packets. Consider a host with the following rule:

  ip6tables -A INPUT -s <untrusted-router> -p icmpv6 --icmpv6-type redirect \
            -j REJECT --reject-with icmp6-adm-prohibited

When a Redirect packet (type 137) arrives from that source, the packet
enters ip6_input(), which invokes NF_HOOK(NF_INET_LOCAL_IN). The
netfilter framework iterates the registered hook entries via
nf_hook_slow(), reaches the ip6tables filter table, and evaluates the
rules. The incoming Redirect matches the rule, causing reject_tg6()
(net/ipv6/netfilter/ip6t_REJECT.c) to be called as the rule's target
action. reject_tg6() calls nf_send_unreach6(), which in turn calls
icmpv6_send() with the Redirect packet as the triggering skb.

Inside icmpv6_send(), is_ineligible() is called to decide whether to
suppress the error. The function detects that the inner protocol is
IPPROTO_ICMPV6 and reads the ICMPv6 type byte. NDISC_REDIRECT is
type 137 (0x89). The check !(*tp & ICMPV6_INFOMSG_MASK) evaluates as
!(0x89 & 0x80) = !(0x80) = false, so is_ineligible() falls through and
returns false and the kernel proceeds to transmit a Destination Unreachable
in response to the Redirect, violating RFC 4443 section 2.4(e.2).

Tested using network namespaces with the above ip6tables rule. Without
the fix, tcpdump confirms a Destination Unreachable is transmitted in
response to the Redirect. With the fix applied and verified under QEMU,
no error is generated.

From the RFC:
(e) An ICMPv6 error message MUST NOT be originated as a result of
    receiving the following:

    (e.1) An ICMPv6 error message.

    (e.2) An ICMPv6 redirect message [IPv6-DISC].

    ...

 net/ipv6/icmp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index efb23807a026..3fdb3a97dd8e 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -157,7 +157,8 @@ static bool is_ineligible(const struct sk_buff *skb)
 		 */
 		if (!tp && frag_off != 0)
 			return false;
-		else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK))
+		else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK) ||
+			 *tp == NDISC_REDIRECT)
 			return true;
 	}
 	return false;
-- 
2.53.0


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

end of thread, other threads:[~2026-06-01  9:49 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-26 10:16 [PATCH] net/ipv6: icmp: fix is_ineligible() to block errors for Redirect packets Sayooj K Karun
2026-05-26 15:40 ` Alexander Lobakin
2026-05-27  9:46 ` [PATCH v2 net] " Sayooj K Karun
2026-05-27 12:15   ` Eric Dumazet
     [not found]     ` <CAFdLOz67Sxne4yXi3hB7Nf0eX=SzE9-P1phG4OzYfrgjQvmcGw@mail.gmail.com>
2026-06-01  7:32       ` Eric Dumazet
2026-06-01  9:49         ` Pablo Neira Ayuso
  -- strict thread matches above, loose matches on Subject: below --
2026-05-27  9:50 Sayooj K Karun

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox