From: Yuyang Huang Date: Fri, 22 May 2026 09:39:06 +0000 (+0900) Subject: ipv4: igmp: annotate data-races around im->users X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=061c0aa740d5d3847cd600a74c66a165bee1fbe0;p=thirdparty%2Flinux.git ipv4: igmp: annotate data-races around im->users /proc/net/igmp walks IPv4 multicast memberships under RCU and prints im->users without holding RTNL, while multicast join and leave paths update the field while holding RTNL. Annotate this intentional lockless snapshot with READ_ONCE() and the matching writers with WRITE_ONCE(). Signed-off-by: Yuyang Huang Reviewed-by: Jiayuan Chen Reviewed-by: Eric Dumazet Reviewed-by: Ido Schimmel Link: https://patch.msgid.link/20260522093906.39764-1-sigefriedhyy@gmail.com Signed-off-by: Jakub Kicinski --- diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 27d120183779..f2aca659b29c 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1541,7 +1541,7 @@ static void ____ip_mc_inc_group(struct in_device *in_dev, __be32 addr, } if (im) { - im->users++; + WRITE_ONCE(im->users, im->users + 1); ip_mc_add_src(in_dev, &addr, mode, 0, NULL, 0); goto out; } @@ -1550,7 +1550,7 @@ static void ____ip_mc_inc_group(struct in_device *in_dev, __be32 addr, if (!im) goto out; - im->users = 1; + WRITE_ONCE(im->users, 1); im->interface = in_dev; in_dev_hold(in_dev); im->multiaddr = addr; @@ -1784,7 +1784,10 @@ void __ip_mc_dec_group(struct in_device *in_dev, __be32 addr, gfp_t gfp) (i = rtnl_dereference(*ip)) != NULL; ip = &i->next_rcu) { if (i->multiaddr == addr) { - if (--i->users == 0) { + int new_users = i->users - 1; + + WRITE_ONCE(i->users, new_users); + if (new_users == 0) { ip_mc_hash_remove(in_dev, i); *ip = i->next_rcu; in_dev->mc_count--; @@ -2977,7 +2980,7 @@ static int igmp_mc_seq_show(struct seq_file *seq, void *v) delta = im->timer.expires - jiffies; seq_printf(seq, "\t\t\t\t%08X %5d %d:%08lX\t\t%d\n", - im->multiaddr, im->users, + im->multiaddr, READ_ONCE(im->users), im->tm_running, im->tm_running ? jiffies_delta_to_clock_t(delta) : 0, im->reporter);