* [PATCH net v3 0/3] ipv6: fix address publication races with addrconf_ifdown
@ 2026-10-09 5:40 Daehyeon Ko
2026-10-09 5:40 ` [PATCH net v3 1/3] ipv6: serialize address publication with device teardown Daehyeon Ko
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Daehyeon Ko @ 2026-10-09 5:40 UTC (permalink / raw)
To: David Ahern, Ido Schimmel
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, netdev, linux-kernel, Daehyeon Ko
The first patch serializes address publication with device teardown by
taking idev->lock before the address hash lock. It uses READ_ONCE() for
the initial lockless state checks and rechecks both dead and disable_ipv6
before publishing.
The second patch handles an address captured by the per-device snapshot
after the initial hash scan. It removes the address from the hash in the
existing list-removal block, after delete notification and before dropping
the list reference.
The third patch initializes a temporary address's public-ifaddr reference
before publishing the object. This closes the remaining interval in which
ifdown could miss the reference and a later store could leak it.
The original deterministic test used a direct internal caller, kprobes and
atomic rendezvous at existing instruction boundaries; it did not add delays
to addrconf.c. A real RA separately reached ipv6_add_addr() with
can_block=false. No new kernel build or runtime test was run for v3.
Changes in v3:
- Use READ_ONCE() for patch 1's initial lockless state checks.
- Add a third patch that passes ifpub through ifa6_config, as suggested by
Ido after the Sashiko review.
- Move patch 2's unhash into the existing lower !keep block and use
73a8bd74e261 as its Fixes commit.
- Rebase onto current net while preserving the v2 cover and first two patch
subjects.
Link: https://lore.kernel.org/r/20261004183639.3773498-1-4ncienth@gmail.com
Link: https://lore.kernel.org/r/179122559913.434549.12720841717630168470@kernel.org
Link: https://lore.kernel.org/r/20261007164548.GA1153540@shredder
Link: https://lore.kernel.org/r/20261007164635.GC1153540@shredder
Daehyeon Ko (3):
ipv6: serialize address publication with device teardown
ipv6: remove ifaddr from hash during ifdown list cleanup
ipv6: initialize temporary ifaddr before publication
include/net/addrconf.h | 1 +
net/ipv6/addrconf.c | 25 +++++++++++++++++++------
2 files changed, 20 insertions(+), 6 deletions(-)
base-commit: af32da41b0327b9c6a37856ba82b6760d6c8d10e
--
2.55.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH net v3 1/3] ipv6: serialize address publication with device teardown 2026-10-09 5:40 [PATCH net v3 0/3] ipv6: fix address publication races with addrconf_ifdown Daehyeon Ko @ 2026-10-09 5:40 ` Daehyeon Ko 2026-10-10 5:43 ` netdev-bot+sashiko 2026-10-09 5:40 ` [PATCH net v3 2/3] ipv6: remove ifaddr from hash during ifdown list cleanup Daehyeon Ko ` (2 subsequent siblings) 3 siblings, 1 reply; 8+ messages in thread From: Daehyeon Ko @ 2026-10-09 5:40 UTC (permalink / raw) To: David Ahern, Ido Schimmel Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev, linux-kernel, Daehyeon Ko ipv6_add_addr() checks idev state before allocating an ifaddr, but publishes the object later. addrconf_ifdown() can mark and detach the idev between the check and publication. This happens when a non-loopback device MTU falls below IPV6_MIN_MTU. A forced interleaving published an address on a dead idev, and later device deletion waited indefinitely for the leaked references. Protect the dead indication with idev->lock and keep that lock across both hash and device-list publication. Use READ_ONCE() for the initial lockless state checks, then recheck both dead and disable_ipv6 before publishing. If teardown wins, reject the unpublished object. Fixes: 8814c4b53381 ("[IPV6] ADDRCONF: Convert addrconf_lock to RCU.") Cc: stable@vger.kernel.org Suggested-by: Ido Schimmel <idosch@nvidia.com> Assisted-by: LLM Signed-off-by: Daehyeon Ko <4ncienth@gmail.com> --- net/ipv6/addrconf.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index c90ee6dd7446cd..77b3b1154d591c 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1095,13 +1095,13 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg, return ERR_PTR(-EADDRNOTAVAIL); } - if (idev->dead) { + if (READ_ONCE(idev->dead)) { NL_SET_ERR_MSG_MOD(extack, "device is going away"); err = -ENODEV; goto out; } - if (idev->cnf.disable_ipv6) { + if (READ_ONCE(idev->cnf.disable_ipv6)) { NL_SET_ERR_MSG_MOD(extack, "IPv6 is disabled on this device"); err = -EACCES; goto out; @@ -1168,14 +1168,20 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg, rcu_read_lock(); - err = ipv6_add_addr_hash(idev->dev, ifa); + write_lock_bh(&idev->lock); + + if (idev->dead) + err = -ENODEV; + else if (READ_ONCE(idev->cnf.disable_ipv6)) + err = -EACCES; + else + err = ipv6_add_addr_hash(idev->dev, ifa); if (err < 0) { + write_unlock_bh(&idev->lock); rcu_read_unlock(); goto out; } - write_lock_bh(&idev->lock); - /* Add to inet6_dev unicast addr list. */ ipv6_link_dev_addr(idev, ifa); @@ -3897,7 +3903,9 @@ static int addrconf_ifdown(struct net_device *dev, bool unregister) * Do not dev_put! */ if (unregister) { + write_lock_bh(&idev->lock); WRITE_ONCE(idev->dead, 1); + write_unlock_bh(&idev->lock); /* protected by rtnl_lock */ RCU_INIT_POINTER(dev->ip6_ptr, NULL); -- 2.55.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net v3 1/3] ipv6: serialize address publication with device teardown 2026-10-09 5:40 ` [PATCH net v3 1/3] ipv6: serialize address publication with device teardown Daehyeon Ko @ 2026-10-10 5:43 ` netdev-bot+sashiko 0 siblings, 0 replies; 8+ messages in thread From: netdev-bot+sashiko @ 2026-10-10 5:43 UTC (permalink / raw) To: 4ncienth Cc: dsahern, idosch, davem, edumazet, kuba, pabeni, horms, netdev, linux-kernel Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider. Critical: 1 · High: 0 (1) · Medium: 0 · Low: 0 If you believe none of the issues are legitimate, please reply to each issue of Medium severity or higher and explain why the AI is wrong. If any of them are legitimate and you plan to respin, please let patchwork know by including "pw-bot: cr" as a separate line at the end of your reply (one such reply per series is enough). - [Critical] At the reviewed commit, the new disable_ipv6 recheck in ipv6_add_addr() under idev->lock does not cover non-unregister… Pre-existing issues: - [High] addrconf_dad_failure() (net/ipv6/addrconf.c) runs from ndisc_recv_ns()/ndisc_recv_na() in softirq without RTNL. -- ipv6: serialize address publication with device teardown This patch makes ipv6_add_addr() hold idev->lock across both the hash and device-list publication. While holding it, the function rechecks idev->dead and disable_ipv6. addrconf_ifdown() now sets idev->dead under idev->lock, so an address can no longer be published on an idev that is being unregistered. > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index c90ee6dd7446c..77b3b1154d591 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c [ ... ] > @@ -1168,14 +1168,20 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg, > > rcu_read_lock(); > > - err = ipv6_add_addr_hash(idev->dev, ifa); > + write_lock_bh(&idev->lock); > + > + if (idev->dead) > + err = -ENODEV; > + else if (READ_ONCE(idev->cnf.disable_ipv6)) > + err = -EACCES; > + else > + err = ipv6_add_addr_hash(idev->dev, ifa); [Severity: Critical] At this commit, does the disable_ipv6 recheck cover a teardown that is not an unregister? The commit message says: "then recheck both dead and disable_ipv6 before publishing. If teardown wins, reject the unpublished object." addrconf_ifdown(dev, false) clears the hash in Step 2 while holding only addrconf_hash_lock. It takes idev->lock later, for the addr_list snapshot. addrconf_disable_change() also writes disable_ipv6 without holding idev->lock. A softirq publisher can insert into a hash bucket that Step 2 has already scanned. Examples are RA prefix handling, DAD failure and tempaddr creation. The publisher can then link the address into addr_list before the snapshot is taken. At this commit, the !keep path of the cleanup loop never unhashes: net/ipv6/addrconf.c:addrconf_ifdown() { ... if (!keep) { write_lock_bh(&idev->lock); list_del_rcu(&ifa->if_list); write_unlock_bh(&idev->lock); in6_ifa_put(ifa); } ... } The final put reaches inet6_ifa_finish_destroy(). That function only does WARN_ON(!hlist_unhashed(&ifp->addr_lst)) and then frees the address via kfree_rcu() anyway. Could this leave a freed inet6_ifaddr on net->ipv6.inet6_addr_lst, where ipv6_chk_addr() and ipv6_get_ifaddr() would later walk it? The next commit in this series, "ipv6: remove ifaddr from hash during ifdown list cleanup", adds hlist_del_init_rcu(&ifa->addr_lst) under addrconf_hash_lock in this path, which fixes it. Since this patch is tagged for stable, should the two be backported together? > if (err < 0) { > + write_unlock_bh(&idev->lock); > rcu_read_unlock(); > goto out; > } > > - write_lock_bh(&idev->lock); > - > /* Add to inet6_dev unicast addr list. */ > ipv6_link_dev_addr(idev, ifa); > [Severity: High] This is a pre-existing issue and was not introduced by this patch. The recheck above does not cover the window after ipv6_add_addr() returns to addrconf_dad_failure(). addrconf_dad_failure() runs from ndisc_recv_ns()/ndisc_recv_na() in softirq without RTNL. For IFA_F_STABLE_PRIVACY addresses it does: net/ipv6/addrconf.c:addrconf_dad_failure() { ... ifp2 = ipv6_add_addr(idev, &cfg, false, NULL); if (IS_ERR(ifp2)) goto lock_errdad; spin_lock_bh(&ifp2->lock); ifp2->stable_privacy_retry = retries; ifp2->state = INET6_IFADDR_STATE_PREDAD; spin_unlock_bh(&ifp2->lock); addrconf_mod_dad_work(ifp2, net->ipv6.sysctl.idgen_delay); ... } addrconf_ifdown() can run on another CPU because of NETDEV_DOWN, disable_ipv6, or NETDEV_CHANGEMTU below IPV6_MIN_MTU. If it snapshots addr_list after ifp2 is linked, it can tear ifp2 down completely before the spin_lock_bh(&ifp2->lock) above: CPU1 (addrconf_ifdown) ifa->state = INET6_IFADDR_STATE_DEAD; __ipv6_ifa_notify(RTM_DELADDR, ifa) ip6_del_rt(net, ifp->rt, false); ifp->rt = NULL; list_del_rcu(&ifa->if_list); in6_ifa_put(ifa); CPU2 (addrconf_dad_failure) ifp2->state = INET6_IFADDR_STATE_PREDAD; addrconf_mod_dad_work(ifp2, ...); Can CPU2 overwrite the DEAD state here and queue DAD work on an address that has already been torn down? Suppose IF_READY is still set and ifp2 has inherited IFA_F_OPTIMISTIC. Then addrconf_dad_work()->addrconf_dad_begin() reaches: if (ifp->flags & IFA_F_OPTIMISTIC) { ip6_ins_rt(net, ifp->rt); At this point ifp->rt is NULL, and __ip6_ins_rt() dereferences rt->fib6_table. IF_READY stays set in two cases: - the NETDEV_CHANGEMTU path calls addrconf_ifdown(dev, true) without a prior NETDEV_DOWN - the link comes back up within idgen_delay Otherwise the address is left in state DAD or POSTDAD. On the final put, inet6_ifa_finish_destroy() then hits: if (ifp->state != INET6_IFADDR_STATE_DEAD) { pr_warn("Freeing alive inet6 address %p\n", ifp); return; } so the ifaddr is never freed. addrconf_dad_start() avoids this by checking for DEAD first: if (ifp->state != INET6_IFADDR_STATE_DEAD) { ifp->state = INET6_IFADDR_STATE_PREDAD; begin_dad = true; } Would a similar check under ifp2->lock in addrconf_dad_failure() work? The PREDAD write itself looks redundant, because ipv6_add_addr() already returns the object in state 0 (PREDAD). No later patch in this series changes addrconf_dad_failure(). [ ... ] -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261009054042.272944-1-4ncienth%40gmail.com ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net v3 2/3] ipv6: remove ifaddr from hash during ifdown list cleanup 2026-10-09 5:40 [PATCH net v3 0/3] ipv6: fix address publication races with addrconf_ifdown Daehyeon Ko 2026-10-09 5:40 ` [PATCH net v3 1/3] ipv6: serialize address publication with device teardown Daehyeon Ko @ 2026-10-09 5:40 ` Daehyeon Ko 2026-10-10 5:43 ` netdev-bot+sashiko 2026-10-09 5:40 ` [PATCH net v3 3/3] ipv6: initialize temporary ifaddr before publication Daehyeon Ko 2026-10-09 5:44 ` [PATCH net v3 0/3] ipv6: fix address publication races with addrconf_ifdown netdev-bot+sinfo 3 siblings, 1 reply; 8+ messages in thread From: Daehyeon Ko @ 2026-10-09 5:40 UTC (permalink / raw) To: David Ahern, Ido Schimmel Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev, linux-kernel, Daehyeon Ko addrconf_ifdown() clears the address hash before snapshotting the per-device address list. When the device is not unregistered, a concurrent ipv6_add_addr() can publish an address after the hash scan and before the list snapshot. The ifdown path then removes the address from the device list and drops its last reference while it is still linked in the hash. This triggers the WARN_ON() in inet6_ifa_finish_destroy(). Remove each non-kept address from the hash immediately before removing it from the per-device list. Keeping it hashed through the delete notification blocks same-address publication until NETDEV_DOWN has been delivered. Unhashing before the list put prevents a stale hash entry. hlist_del_init_rcu() is safe when the earlier hash scan already removed the address. Fixes: 73a8bd74e261 ("ipv6: Revert 'administrative down' address handling changes.") Cc: stable@vger.kernel.org Reported-by: Ido Schimmel <idosch@nvidia.com> Link: https://lore.kernel.org/r/20261004135117.GA206930@shredder Suggested-by: Ido Schimmel <idosch@nvidia.com> Assisted-by: LLM Signed-off-by: Daehyeon Ko <4ncienth@gmail.com> --- net/ipv6/addrconf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 77b3b1154d591c..5a7e7129d43466 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -4027,6 +4027,10 @@ static int addrconf_ifdown(struct net_device *dev, bool unregister) } if (!keep) { + spin_lock_bh(&net->ipv6.addrconf_hash_lock); + hlist_del_init_rcu(&ifa->addr_lst); + spin_unlock_bh(&net->ipv6.addrconf_hash_lock); + write_lock_bh(&idev->lock); list_del_rcu(&ifa->if_list); write_unlock_bh(&idev->lock); -- 2.55.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net v3 2/3] ipv6: remove ifaddr from hash during ifdown list cleanup 2026-10-09 5:40 ` [PATCH net v3 2/3] ipv6: remove ifaddr from hash during ifdown list cleanup Daehyeon Ko @ 2026-10-10 5:43 ` netdev-bot+sashiko 0 siblings, 0 replies; 8+ messages in thread From: netdev-bot+sashiko @ 2026-10-10 5:43 UTC (permalink / raw) To: 4ncienth Cc: dsahern, idosch, davem, edumazet, kuba, pabeni, horms, netdev, linux-kernel Thank you for your contribution! Sashiko AI review found more severe issue(s) in other patches of this series. This mail is only an FYI, in case you want to address the nit picks below when you respin. Low priority / nit picks for your consideration: - [Low] The commit message understates the bug being fixed. -- ipv6: remove ifaddr from hash during ifdown list cleanup This commit unhashes each non-kept address in addrconf_ifdown() just before it is removed from the per-device list. That closes a race where ipv6_add_addr() publishes an address after the Step 2 hash scan and before the list snapshot. Link: https://lore.kernel.org/r/20261004135117.GA206930@shredder > The ifdown path then removes the address from the device list and drops > its last reference while it is still linked in the hash. This triggers > the WARN_ON() in inet6_ifa_finish_destroy(). [Severity: Low] The code change looks correct. Does the commit message understate what happens before this patch, though? The WARN_ON() in inet6_ifa_finish_destroy() does not stop execution. In this race, addrconf_ifdown() has already set ifa->state to INET6_IFADDR_STATE_DEAD, so the "Freeing alive" early return is skipped and the object is freed: net/ipv6/addrconf.c:inet6_ifa_finish_destroy() { WARN_ON(!hlist_unhashed(&ifp->addr_lst)); ... if (ifp->state != INET6_IFADDR_STATE_DEAD) { pr_warn("Freeing alive inet6 address %p\n", ifp); return; } kfree_rcu(ifp, rcu); } That leaves a freed ifa linked in net->ipv6.inet6_addr_lst. Later walks of that hash chain would read freed memory. Examples include ipv6_get_ifaddr() and ipv6_chk_addr() under RCU, ipv6_chk_same_addr() from ipv6_add_addr_hash(), and the Step 2 scan in the next addrconf_ifdown(). One way to reach it is ipv6_add_addr() called from RA processing through addrconf_prefix_rcv_add_addr(), racing with a non-unregister addrconf_ifdown(). > Unhashing before the list put prevents a stale hash entry. Could the message say that the stale hash entry points to freed memory, which makes this a use-after-free and not only a WARN? -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261009054042.272944-1-4ncienth%40gmail.com ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net v3 3/3] ipv6: initialize temporary ifaddr before publication 2026-10-09 5:40 [PATCH net v3 0/3] ipv6: fix address publication races with addrconf_ifdown Daehyeon Ko 2026-10-09 5:40 ` [PATCH net v3 1/3] ipv6: serialize address publication with device teardown Daehyeon Ko 2026-10-09 5:40 ` [PATCH net v3 2/3] ipv6: remove ifaddr from hash during ifdown list cleanup Daehyeon Ko @ 2026-10-09 5:40 ` Daehyeon Ko 2026-10-10 5:43 ` netdev-bot+sashiko 2026-10-09 5:44 ` [PATCH net v3 0/3] ipv6: fix address publication races with addrconf_ifdown netdev-bot+sinfo 3 siblings, 1 reply; 8+ messages in thread From: Daehyeon Ko @ 2026-10-09 5:40 UTC (permalink / raw) To: David Ahern, Ido Schimmel Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev, linux-kernel, Daehyeon Ko ipv6_create_tempaddr() holds a reference to the public ifaddr, publishes the new temporary address through ipv6_add_addr(), and only then stores the reference in ifpub. addrconf_ifdown() can remove the temporary address between publication and that store. It then observes a NULL ifpub and cannot drop the public ifaddr reference. The later store survives until the temporary ifaddr is destroyed, pinning the public ifaddr, inet6_dev and net_device. Later device deletion can wait indefinitely for these references. Pass the public ifaddr in ifa6_config and initialize ifpub before adding the temporary address to either the hash or per-device lists. On success the existing reference transfers to the temporary ifaddr. On error it remains owned and released by ipv6_create_tempaddr(). Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reported-by: Sashiko <netdev-bot+sashiko@kernel.org> Closes: https://lore.kernel.org/r/179122559913.434549.12720841717630168470@kernel.org Link: https://lore.kernel.org/r/20261007164548.GA1153540@shredder Suggested-by: Ido Schimmel <idosch@nvidia.com> Assisted-by: LLM Signed-off-by: Daehyeon Ko <4ncienth@gmail.com> --- include/net/addrconf.h | 1 + net/ipv6/addrconf.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/net/addrconf.h b/include/net/addrconf.h index e6764245995f25..848bed306ec98f 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -81,6 +81,7 @@ struct ifa6_config { u8 ifa_proto; const struct in6_addr *peer_pfx; + struct inet6_ifaddr *ifpub; u32 rt_priority; u32 ifa_flags; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 5a7e7129d43466..699d058f5c7868 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1159,6 +1159,7 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg, ifa->tokenized = false; ifa->rt = f6i; + ifa->ifpub = cfg->ifpub; ifa->idev = idev; in6_dev_hold(idev); @@ -1493,6 +1494,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, bool block) cfg.pfx = &addr; cfg.scope = ipv6_addr_scope(cfg.pfx); + cfg.ifpub = ifp; ift = ipv6_add_addr(idev, &cfg, block, NULL); if (IS_ERR(ift)) { @@ -1504,7 +1506,6 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, bool block) } spin_lock_bh(&ift->lock); - ift->ifpub = ifp; ift->cstamp = now; ift->tstamp = tmp_tstamp; spin_unlock_bh(&ift->lock); -- 2.55.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net v3 3/3] ipv6: initialize temporary ifaddr before publication 2026-10-09 5:40 ` [PATCH net v3 3/3] ipv6: initialize temporary ifaddr before publication Daehyeon Ko @ 2026-10-10 5:43 ` netdev-bot+sashiko 0 siblings, 0 replies; 8+ messages in thread From: netdev-bot+sashiko @ 2026-10-10 5:43 UTC (permalink / raw) To: 4ncienth Cc: dsahern, idosch, davem, edumazet, kuba, pabeni, horms, netdev, linux-kernel Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider. Critical: 0 · High: 0 · Medium: 1 · Low: 0 If you believe none of the issues are legitimate, please reply to each issue of Medium severity or higher and explain why the AI is wrong. If any of them are legitimate and you plan to respin, please let patchwork know by including "pw-bot: cr" as a separate line at the end of your reply (one such reply per series is enough). - [Medium] The patch makes the temporary ifaddr visible to manage_tempaddrs() before ipv6_create_tempaddr() has finished setting… -- ipv6: initialize temporary ifaddr before publication This patch passes the public ifaddr to ipv6_add_addr() through ifa6_config, so ift->ifpub is set before the temporary address goes on the hash and per-device lists. That closes a window where addrconf_ifdown() could remove the temporary address while ifpub was still NULL and leak the public ifaddr reference. Link: https://lore.kernel.org/r/20261007164548.GA1153540@shredder > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index 5a7e7129d4346..699d058f5c786 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c > @@ -1159,6 +1159,7 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg, > ifa->tokenized = false; > > ifa->rt = f6i; > + ifa->ifpub = cfg->ifpub; > > ifa->idev = idev; > in6_dev_hold(idev); [ ... ] > @@ -1504,7 +1506,6 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, bool block) > } > > spin_lock_bh(&ift->lock); > - ift->ifpub = ifp; > ift->cstamp = now; > ift->tstamp = tmp_tstamp; > spin_unlock_bh(&ift->lock); [Severity: Medium] Now that ifpub is set before publication, can manage_tempaddrs() find the new ift before these cstamp and tstamp stores run? Before this patch, ifpub stayed NULL until this ift->lock section. manage_tempaddrs() skips entries that don't match ifpub, so it ignored the new address until all three fields were final: net/ipv6/addrconf.c:manage_tempaddrs() { ... list_for_each_entry(ift, &idev->tempaddr_list, tmp_list) { ... if (ifp != ift->ifpub) continue; ... ift->valid_lft = valid_lft; ift->prefered_lft = prefered_lft; ift->tstamp = now; ... } There is now a window between write_unlock_bh(&idev->lock) in ipv6_add_addr() and the spin_lock_bh(&ift->lock) above. The NETDEV_UP inet6addr notifier chain also runs inside this window. The RA softirq path does not hold RTNL. It doesn't seem to be serialized against ipv6_create_tempaddr() callers such as addrconf_verify_rtnl() or addrconf_dad_stop(): CPU1 ipv6_create_tempaddr(ifp) tmp_tstamp = ifp->tstamp; ipv6_add_addr() ift published with ift->ifpub == ifp CPU2 (RA softirq) addrconf_prefix_rcv_add_addr() WRITE_ONCE(ifp->tstamp, now); manage_tempaddrs(in6_dev, ifp, valid_lft, prefered_lft, create, now) ift->valid_lft = valid_lft; ift->prefered_lft = prefered_lft; ift->tstamp = now; CPU1 ift->cstamp = now; ift->tstamp = tmp_tstamp; Would ift then have lifetimes computed relative to CPU2's now, but a tstamp taken from the older tmp_tstamp? If so, the temporary address loses (now - tmp_tstamp) seconds of preferred and valid lifetime. addrconf_verify() would then deprecate, regenerate or expire it early. Could cstamp and tstamp also be set before publication? One way is to pass the timestamp through ifa6_config, or to set it in ipv6_add_addr() next to ifpub. Then nothing in ift is written after it becomes reachable. -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261009054042.272944-1-4ncienth%40gmail.com ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net v3 0/3] ipv6: fix address publication races with addrconf_ifdown 2026-10-09 5:40 [PATCH net v3 0/3] ipv6: fix address publication races with addrconf_ifdown Daehyeon Ko ` (2 preceding siblings ...) 2026-10-09 5:40 ` [PATCH net v3 3/3] ipv6: initialize temporary ifaddr before publication Daehyeon Ko @ 2026-10-09 5:44 ` netdev-bot+sinfo 3 siblings, 0 replies; 8+ messages in thread From: netdev-bot+sinfo @ 2026-10-09 5:44 UTC (permalink / raw) To: Daehyeon Ko Cc: David Ahern, Ido Schimmel, David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev, linux-kernel Hi! This is an automated message. This series looks like a fix, but its commit messages seem to be missing some information: - Whether the issue was actually triggered, or is only theoretical (e.g. found by code inspection). If it was triggered please include the symptoms, like the stack trace or error messages. Please do not repost the series just to address the above. Instead, reply to this email with the missing information, so that reviewers can take it into account. If the series needs another revision for other reasons, please include the information in the commit messages then. The evaluation is done by an LLM so it may be wrong, if you think that is the case please reply and explain. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-10-10 5:43 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-09 5:40 [PATCH net v3 0/3] ipv6: fix address publication races with addrconf_ifdown Daehyeon Ko 2026-10-09 5:40 ` [PATCH net v3 1/3] ipv6: serialize address publication with device teardown Daehyeon Ko 2026-10-10 5:43 ` netdev-bot+sashiko 2026-10-09 5:40 ` [PATCH net v3 2/3] ipv6: remove ifaddr from hash during ifdown list cleanup Daehyeon Ko 2026-10-10 5:43 ` netdev-bot+sashiko 2026-10-09 5:40 ` [PATCH net v3 3/3] ipv6: initialize temporary ifaddr before publication Daehyeon Ko 2026-10-10 5:43 ` netdev-bot+sashiko 2026-10-09 5:44 ` [PATCH net v3 0/3] ipv6: fix address publication races with addrconf_ifdown netdev-bot+sinfo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox