Netdev List
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Sayooj Karun <sayooj@aerlync.com>
Cc: Eric Dumazet <edumazet@google.com>,
	Florian Westphal <fw@strlen.de>,
	netdev@vger.kernel.org, dsahern@kernel.org, idosch@nvidia.com,
	davem@davemloft.net, kuba@kernel.org, pabeni@redhat.com,
	horms@kernel.org, linux-kernel@vger.kernel.org,
	aleksander.lobakin@intel.com
Subject: Re: [PATCH v2 net] net/ipv6: icmp: fix is_ineligible() to block errors for Redirect packets
Date: Mon, 1 Jun 2026 11:49:23 +0200	[thread overview]
Message-ID: <ah1VoxXLbRAZIEC3@chamomile> (raw)
In-Reply-To: <CANn89i+KFK5ap6S_wdR2eJUbQc9aqdXtAnGbQ2tqe6R_bGQiSQ@mail.gmail.com>

Hi,

On Mon, Jun 01, 2026 at 12:32:50AM -0700, Eric Dumazet wrote:
> On Mon, Jun 1, 2026 at 12:23 AM Sayooj Karun <sayooj@aerlync.com> wrote:
> >
> > Hi Eric,
> >
> > Thank you for the review.
> > The concern about REJECT becoming DROP for Redirect packets is correct, and that is intentional.
> > RFC 4443  section 2.4(e.2) mandates unconditionally that the originator MUST NOT send an ICMPv6 error in response to a Redirect message.
> > There is no exception for netfilter policy.
>
> Really? Have you CC netfilter maintainers?

Thanks for Cc'ing.

> > To your question "how would the kernel send a reply?" : it cannot, as per the RFC.
> > A user who writes -j REJECT on ICMPv6 Redirect naturally expects an error to be sent back, but the protocol leaves no room for that.
> > RFC 4443  Section 2.4(e.2) forbids it outright. The pre-patch behavior (sending Destination Unreachable in response to Redirect) was the RFC violation.
> >
> > The same suppression already exists in is_ineligible() for section 2.4(e.1): a REJECT rule targeting any ICMPv6 error type (types 0–127) already silently drops without generating an error, because !(*tp & ICMPV6_INFOMSG_MASK)
> > returns true. This patch applies the same logic to  section 2.4(e.2) (Redirect, type 137). Both are entries in the same "MUST NOT" list in RFC 4443.
> > If the goal is to block incoming Redirects, -j DROP is the right tool. Using -j REJECT on Redirect packets was never RFC-compliant. The error response it tried to send was never allowed by the protocol.

Netfilter, through policy, allows to modify the box behaviour in
different ways that makes it non-RFC compliant.

But there is code already code such as nf_skb_is_icmp_unreach() which
does not allow to reject a icmp dest unreach with another icmp dest
unreach.

Also looking at your patch, how does it fix the REJECT case? Maybe you
can propose a patch for nf-next as enhancement that can be reviewed to
netfilter-devel@vger.kernel.org.

Thanks.

> > Thanks,
> > Sayooj
> >
> > On Wed, May 27, 2026 at 5:45 PM Eric Dumazet <edumazet@google.com> wrote:
> >>
> >> On Wed, May 27, 2026 at 2:46 AM Sayooj K Karun <sayooj@aerlync.com> wrote:
> >> >
> >> > 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
> >> >
> >>
> >> You are saying that after your patch, this ip6ables will no longer
> >> send a packet, and will effectively DROP
> >> the packet.
> >> This might break user choice/expectations/policy.
> >> If the user wanted a DROP, they would have instead specified "-j DROP"
> >>
> >> Apart from the netfilter world which is free to implement its own
> >> interpretation of the RFC,
> >> how would the kernel send a reply?
> >>
> >>
> >> > 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
> >> >

  reply	other threads:[~2026-06-01  9:49 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
  -- strict thread matches above, loose matches on Subject: below --
2026-05-27  9:50 Sayooj K Karun

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ah1VoxXLbRAZIEC3@chamomile \
    --to=pablo@netfilter.org \
    --cc=aleksander.lobakin@intel.com \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=fw@strlen.de \
    --cc=horms@kernel.org \
    --cc=idosch@nvidia.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sayooj@aerlync.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox