All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Horman <horms@kernel.org>
To: equinox@diac24.net
Cc: Simon Horman <horms@kernel.org>,
	pabeni@redhat.com, kuba@kernel.org, idosch@nvidia.com,
	dsahern@kernel.org, davem@davemloft.net, edumazet@google.com,
	corbet@lwn.net, skhan@linuxfoundation.org, fmancera@suse.de,
	lorenzo@google.com, maze@google.com, prohr@google.com,
	netdev@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kselftest@vger.kernel.org, furry13@gmail.com
Subject: Re: [PATCH net-next 7/9] net/ipv6: support RFC6724 rule 5.5 via subtrees
Date: Tue, 21 Jul 2026 14:50:14 +0100	[thread overview]
Message-ID: <20260721135013.387122-2-horms@kernel.org> (raw)
In-Reply-To: <20260714094030.136317-8-equinox@diac24.net>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
https://sashiko.dev/#/patchset/20260714094030.136317-2-equinox@diac24.net?part=7
---
--- Patch [7]: [PATCH net-next 7/9] net/ipv6: support RFC6724 rule 5.5 via subtrees ---
commit 8c6cdd876548668f6d35fa2db4feb39f16c09a62
Author: David 'equinox' Lamparter <equinox@diac24.net>

net/ipv6: support RFC6724 rule 5.5 via subtrees

This commit implements RFC6724 rule 5.5 for IPv6 source address selection.
It introduces subtrees logic to prefer source addresses in a prefix advertised
by the chosen next-hop.

> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 0ba46ed518a9a..f5c04928aa142 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
[ ... ]
> @@ -1593,6 +1595,80 @@ static bool ipv6_allow_optimistic_dad(const struct net *net,
>  #endif
>  }
>  
> +/* "source address is preferable if the chosen nexthop advertised it as a PIO"
> + * => consider 'advertised as a PIO' to be 'the routes for the source's subtree
> + *    include one with the same nexthop'
> + *
> + * NB: there is no backtracking in the subtree here, this is intentional -
> + * each prefix seen (and accepted) in PIOs creates essentially a "zone" which
> + * is our search scope.
> + */
> +static int ipv6_saddr_rule5p5(struct ipv6_saddr_score *score,
> +			      struct ipv6_saddr_dst *saddr_dst)
> +{
> +	const struct rt6_info *rt, *cmp_rt;
> +	struct dst_entry *cmp_dst;
> +	struct fib6_info *f6i;
> +	int ret = 0;
> +
> +	rt = container_of(saddr_dst->dst, struct rt6_info, dst);
> +
> +	/* fl6->saddr is ::, cf. check at the top of ipv6_common_get_saddr() */
> +	saddr_dst->fl6->saddr = score->ifa->addr;
> +	cmp_dst = ip6_route_output(saddr_dst->net, saddr_dst->sk,
> +				   saddr_dst->fl6);

[Severity: High]
When ipv6_saddr_rule5p5() passes the caller-provided saddr_dst->fl6 pointer
into ip6_route_output(), does this permanently alter the flow state?

ip6_route_output() calls ip6_route_output_flags_noref(), which
unconditionally mutates fields in the flow struct, such as setting
flowi6_iif to LOOPBACK_IFINDEX. It can also call l3mdev_update_flow()
to alter flowi6_oif.

Since the code only clears the injected saddr via memset() below, could this
cause silent corruption of the network flow state for subsequent lookups,
potentially breaking policy routing or VRF logic?

> +	memset(&saddr_dst->fl6->saddr, 0, sizeof(saddr_dst->fl6->saddr));
> +
> +	if (cmp_dst->error)
> +		goto out_release_dst;
> +
> +	cmp_rt = container_of(cmp_dst, struct rt6_info, dst);
> +
> +	/* this must work if _any_ nexthop matches; the non-subtree best may
> +	 * not be in same order as subtree best
> +	 */
> +	for (f6i = rcu_dereference(cmp_rt->from); f6i;
> +	     f6i = rcu_dereference(f6i->fib6_next)) {
> +		struct fib6_nh *f6n = f6i->fib6_nh;

[Severity: High]
Can this cause a slab-out-of-bounds read if the route uses an external
nexthop?

When an IPv6 route is configured with an external nexthop, fib6_info_alloc()
allocates the fib6_info object without space for the inline fib6_nh flexible
array, and instead sets f6i->nh.

Is it safe to unconditionally dereference f6i->fib6_nh without checking if
f6i->nh is in use?

> +		struct fib6_info *sibling;
> +
> +		/* non-subtree route: says nothing about router advertising this source */
> +		if (f6i->fib6_src.plen == 0)
> +			continue;
> +
> +		if (f6n->nh_common.nhc_dev != saddr_dst->dst->dev ||
> +		    f6n->nh_common.nhc_gw_family != AF_INET6)
> +			continue;
> +
> +		if (ipv6_addr_equal(&f6n->nh_common.nhc_gw.ipv6,
> +				    &rt->rt6i_gateway)) {
> +			ret = 1;
> +			goto out_release_dst;
> +		}
> +
> +		if (!f6i->fib6_nsiblings)
> +			continue;
> +
> +		list_for_each_entry(sibling, &f6i->fib6_siblings, fib6_siblings) {

[Severity: High]
Is this list traversal safe to perform without RCU primitives?

The fib6_siblings list is actively mutated by the routing subsystem using RCU
list primitives like list_add_tail_rcu() and list_del_rcu().

Since ipv6_saddr_rule5p5() is executed locklessly under the rcu_read_lock()
held by its caller, should this be using list_for_each_entry_rcu() to avoid
reading torn or uninitialized pointers on weakly ordered architectures?

> +			f6n = sibling->fib6_nh;

[Severity: High]
Similar to the issue above, can this unconditionally access an unallocated
fib6_nh array if the sibling route uses an external nexthop?

> +
> +			if (f6n->nh_common.nhc_dev != saddr_dst->dst->dev ||
> +			    f6n->nh_common.nhc_gw_family != AF_INET6)
> +				continue;
> +
> +			if (ipv6_addr_equal(&f6n->nh_common.nhc_gw.ipv6,
> +					    &rt->rt6i_gateway)) {
> +				ret = 1;
> +				goto out_release_dst;
> +			}
> +		}
> +	}
> +
> +out_release_dst:
> +	dst_release(cmp_dst);
> +	return ret;
> +}
[ ... ]

  reply	other threads:[~2026-07-21 13:50 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-14  9:40 [PATCH net-next 0/9] RFC 6724 rule 5.5 support David 'equinox' Lamparter
2026-07-14  9:40 ` [PATCH net-next 1/9] net/ipv6: fix lookup for ::/0 (non-)subtree route David 'equinox' Lamparter
2026-07-14  9:40 ` [PATCH net-next 2/9] net/ipv6: flatten ip6_route_get_saddr David 'equinox' Lamparter
2026-07-14  9:40 ` [PATCH net-next 3/9] net/ipv6: create ipv6_fl_get_saddr David 'equinox' Lamparter
2026-07-14  9:40 ` [PATCH net-next 4/9] net/ipv6: use ipv6_fl_get_saddr in output David 'equinox' Lamparter
2026-07-14  9:40 ` [PATCH net-next 5/9] net/ipv6: drop ip6_route_get_saddr David 'equinox' Lamparter
2026-07-14  9:40 ` [PATCH net-next 6/9] net/ipv6: flip IPV6_SUBTREES default to Y David 'equinox' Lamparter
2026-07-14  9:40 ` [PATCH net-next 7/9] net/ipv6: support RFC6724 rule 5.5 via subtrees David 'equinox' Lamparter
2026-07-21 13:50   ` Simon Horman [this message]
2026-07-21 14:37     ` David 'equinox' Lamparter
2026-07-14  9:40 ` [PATCH net-next 8/9] selftests: net: RFC6724 rule 5.5 tests David 'equinox' Lamparter
2026-07-21 13:50   ` Simon Horman
2026-07-14  9:40 ` [PATCH net-next 9/9] net: document RFC6724 rule 5.5 implementation David 'equinox' Lamparter
2026-07-14 13:01   ` Jonathan Corbet
2026-07-14 17:16     ` David 'equinox' Lamparter
2026-07-14 17:31       ` Jonathan Corbet

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=20260721135013.387122-2-horms@kernel.org \
    --to=horms@kernel.org \
    --cc=corbet@lwn.net \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=equinox@diac24.net \
    --cc=fmancera@suse.de \
    --cc=furry13@gmail.com \
    --cc=idosch@nvidia.com \
    --cc=kuba@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=lorenzo@google.com \
    --cc=maze@google.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=prohr@google.com \
    --cc=skhan@linuxfoundation.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.