Thread (13 messages) 13 messages, 4 authors, 2d ago

[PATCH net v3 3/3] ipv6: initialize temporary ifaddr before publication

flat view
WARM2d SUPERSEDED

From: Daehyeon Ko <hidden>
Date: 2026-10-09 05:41:05
Also in: lkml
Subsystem: networking [general], networking [ipv4/ipv6], the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, David Ahern, Ido Schimmel, Linus Torvalds

Revision v3 of 2 in this series.

Revisions (2)
  1. v3 current
  2. v4 [diff vs current]
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 (local)
Link: https://lore.kernel.org/r/20261007164548.GA1153540@shredder (local)
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Assisted-by: LLM
Signed-off-by: Daehyeon Ko <redacted>
---
 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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help