diff options
| author | Eric Dumazet <edumazet@google.com> | 2026-08-28 08:45:28 +0000 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-08-31 17:54:45 -0700 |
| commit | c073d1b070f171d206b19c98d71739a97f15b3f1 (patch) | |
| tree | 087b1876144b9b374909096134cf85df5c1d1543 /include | |
| parent | 93b49239840b91313adbd77b8b52993eff2d08c1 (diff) | |
| download | linux-stable-c073d1b070f171d206b19c98d71739a97f15b3f1.tar.gz linux-stable-c073d1b070f171d206b19c98d71739a97f15b3f1.zip | |
ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source()
pmc->sflist is read locklessly under rcu_read_lock() by
inet6_mc_check() during packet reception in the UDP and RAW
multicast receive paths.
ip6_mc_source() mutated psl->sl_addr and psl->sl_count in-place
when adding or removing a source filter. Additionally, when expanding
the filter buffer, newpsl was published via rcu_assign_pointer()
before writing the new source into the array.
Because 16-byte struct in6_addr writes are not atomic and array
shifting is not synchronized with RCU readers, concurrent readers in
inet6_mc_check() could read torn IPv6 addresses or observe
duplicated/missed source entries.
Fix this by switching ip6_mc_source() to copy-on-write RCU updates:
allocate and fully populate newpsl before publishing it via
rcu_assign_pointer(), and reclaim the old filter via kfree_rcu(),
matching ip6_mc_msfilter().
Also remove the now unused IP6_SFBLOCK macro.
Fixes: 882ba1f73c06 ("mld: convert ipv6_mc_socklist->sflist to RCU")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Taehee Yoo <ap420073@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260828084531.1826790-3-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/net/if_inet6.h | 2 |
1 files changed, 0 insertions, 2 deletions
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 238ad3349456..795fb41b45f5 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -88,8 +88,6 @@ struct ip6_sf_socklist { struct in6_addr sl_addr[] __counted_by(sl_max); }; -#define IP6_SFBLOCK 10 /* allocate this many at once */ - struct ipv6_mc_socklist { struct in6_addr addr; int ifindex; |
