From: Eric Dumazet <edumazet@google.com>
To: "David S . Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>, Ido Schimmel <idosch@nvidia.com>,
David Ahern <dsahern@kernel.org>,
netdev@vger.kernel.org, eric.dumazet@gmail.com,
Eric Dumazet <edumazet@google.com>,
Taehee Yoo <ap420073@gmail.com>
Subject: [PATCH net 4/5] ipv6: mcast: use rcu_assign_pointer() for __rcu list updates
Date: Wed, 26 Aug 2026 10:37:10 +0000 [thread overview]
Message-ID: <20260826103711.3302915-5-edumazet@google.com> (raw)
In-Reply-To: <20260826103711.3302915-1-edumazet@google.com>
Several places in net/ipv6/mcast.c update RCU-protected lists
(np->ipv6_mc_list, idev->mc_list, idev->mc_tomb) using direct pointer
assignments instead of rcu_assign_pointer():
1. In __ipv6_dev_mc_dec(), unlinking a group from idev->mc_list did:
*map = ma->next;
without rcu_assign_pointer() while concurrent readers traverse
idev->mc_list locklessly under rcu_read_lock().
2. In ipv6_sock_mc_drop() and __ipv6_sock_mc_close(), unlinking a group
from np->ipv6_mc_list directly assigned *lnk = mc_lst->next and
np->ipv6_mc_list = mc_lst->next without rcu_assign_pointer(), racing
with lockless readers in inet6_mc_check().
3. In __ipv6_sock_mc_join(), mc_lst->next was initialized to
np->ipv6_mc_list via raw assignment before publishing mc_lst.
4. In mld_del_delrec() and __ipv6_dev_mc_inc(), __rcu source pointers
passed into rcu_assign_pointer() lacked explicit dereference helpers.
Fix these by consistently using rcu_assign_pointer() along with
mc_dereference() / sock_dereference().
Fixes: 456b61bca8ee ("ipv6: mcast: RCU conversion")
Fixes: 88e2ca308094 ("mld: convert ifmcaddr6 to RCU")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Taehee Yoo <ap420073@gmail.com>
---
net/ipv6/mcast.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 44fdde940dcdcd16a7642b2be60c6866c574ce92..a90dddba719726f36e0d5176c5e0574d1a488d5e 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -240,7 +240,8 @@ static int __ipv6_sock_mc_join(struct sock *sk, int ifindex,
return err;
}
- mc_lst->next = np->ipv6_mc_list;
+ rcu_assign_pointer(mc_lst->next,
+ sock_dereference(np->ipv6_mc_list, sk));
rcu_assign_pointer(np->ipv6_mc_list, mc_lst);
return 0;
@@ -300,7 +301,8 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
lnk = &mc_lst->next) {
if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
ipv6_addr_equal(&mc_lst->addr, addr)) {
- *lnk = mc_lst->next;
+ rcu_assign_pointer(*lnk,
+ sock_dereference(mc_lst->next, sk));
__ipv6_sock_mc_drop(sk, mc_lst);
return 0;
}
@@ -333,7 +335,8 @@ void __ipv6_sock_mc_close(struct sock *sk)
struct ipv6_mc_socklist *mc_lst;
while ((mc_lst = sock_dereference(np->ipv6_mc_list, sk)) != NULL) {
- np->ipv6_mc_list = mc_lst->next;
+ rcu_assign_pointer(np->ipv6_mc_list,
+ sock_dereference(mc_lst->next, sk));
__ipv6_sock_mc_drop(sk, mc_lst);
}
}
@@ -799,9 +802,11 @@ static void mld_del_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im)
if (!pmc)
return;
if (pmc_prev)
- rcu_assign_pointer(pmc_prev->next, pmc->next);
+ rcu_assign_pointer(pmc_prev->next,
+ mc_dereference(pmc->next, idev));
else
- rcu_assign_pointer(idev->mc_tomb, pmc->next);
+ rcu_assign_pointer(idev->mc_tomb,
+ mc_dereference(pmc->next, idev));
im->idev = pmc->idev;
if (im->mca_sfmode == MCAST_INCLUDE) {
@@ -981,7 +986,7 @@ static int __ipv6_dev_mc_inc(struct net_device *dev,
return -ENOMEM;
}
- rcu_assign_pointer(mc->next, idev->mc_list);
+ rcu_assign_pointer(mc->next, mc_dereference(idev->mc_list, idev));
rcu_assign_pointer(idev->mc_list, mc);
mld_del_delrec(idev, mc);
@@ -1015,7 +1020,8 @@ int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr)
WRITE_ONCE(ma->mca_users, new_users);
if (new_users == 0) {
- *map = ma->next;
+ rcu_assign_pointer(*map,
+ mc_dereference(ma->next, idev));
igmp6_group_dropped(ma);
inet6_ifmcaddr_notify(idev->dev, ma,
--
2.55.0.860.g4b6b3295ed-goog
next prev parent reply other threads:[~2026-08-26 10:37 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-26 10:37 [PATCH net 0/5] ipv6: mcast: RCU and timer fixes Eric Dumazet
2026-08-26 10:37 ` [PATCH net 1/5] ipv6: mcast: fix RCU list diversion in ip6_mc_del1_src() Eric Dumazet
2026-08-26 10:37 ` [PATCH net 2/5] ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source() Eric Dumazet
2026-08-27 19:42 ` Jakub Kicinski
2026-08-27 20:19 ` Eric Dumazet
2026-08-26 10:37 ` [PATCH net 3/5] ipv6: mcast: fix delay calculation in igmp6_join_group() Eric Dumazet
2026-08-27 19:42 ` Jakub Kicinski
2026-08-27 20:02 ` Eric Dumazet
2026-08-27 20:08 ` Jakub Kicinski
2026-08-26 10:37 ` Eric Dumazet [this message]
2026-08-26 10:37 ` [PATCH net 5/5] ipv6: mcast: use jiffies_delta_to_clock_t() in igmp6_mc_seq_show() Eric Dumazet
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=20260826103711.3302915-5-edumazet@google.com \
--to=edumazet@google.com \
--cc=ap420073@gmail.com \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=eric.dumazet@gmail.com \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.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 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.