Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ipmr: Annotate access to mrt->mroute_do_{pim,assert,wrvifwhole}.

These fields in struct mr_table are updated in ip_mroute_setsockopt()
under RTNL:

* mroute_do_pim
* mroute_do_assert
* mroute_do_wrvifwhole

However, ip_mroute_getsockopt() does not hold RTNL and read the first
two fields locklessly, and ip_mr_forward() reads all the three under
RCU. pim_rcv_v1() also reads mroute_do_pim locklessly.

Let's use WRITE_ONCE() and READ_ONCE() for them.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260228221800.1082070-3-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Kuniyuki Iwashima and committed by
Jakub Kicinski
261950e0 05068eaa

+10 -10
+10 -10
net/ipv4/ipmr.c
··· 1506 1506 ret = -EFAULT; 1507 1507 break; 1508 1508 } 1509 - mrt->mroute_do_assert = val; 1509 + WRITE_ONCE(mrt->mroute_do_assert, val); 1510 1510 break; 1511 1511 case MRT_PIM: 1512 1512 if (!ipmr_pimsm_enabled()) { ··· 1525 1525 do_wrvifwhole = (val == IGMPMSG_WRVIFWHOLE); 1526 1526 val = !!val; 1527 1527 if (val != mrt->mroute_do_pim) { 1528 - mrt->mroute_do_pim = val; 1529 - mrt->mroute_do_assert = val; 1530 - mrt->mroute_do_wrvifwhole = do_wrvifwhole; 1528 + WRITE_ONCE(mrt->mroute_do_pim, val); 1529 + WRITE_ONCE(mrt->mroute_do_assert, val); 1530 + WRITE_ONCE(mrt->mroute_do_wrvifwhole, do_wrvifwhole); 1531 1531 } 1532 1532 break; 1533 1533 case MRT_TABLE: ··· 1610 1610 case MRT_PIM: 1611 1611 if (!ipmr_pimsm_enabled()) 1612 1612 return -ENOPROTOOPT; 1613 - val = mrt->mroute_do_pim; 1613 + val = READ_ONCE(mrt->mroute_do_pim); 1614 1614 break; 1615 1615 case MRT_ASSERT: 1616 - val = mrt->mroute_do_assert; 1616 + val = READ_ONCE(mrt->mroute_do_assert); 1617 1617 break; 1618 1618 default: 1619 1619 return -ENOPROTOOPT; ··· 2037 2037 2038 2038 atomic_long_inc(&c->_c.mfc_un.res.wrong_if); 2039 2039 2040 - if (true_vifi >= 0 && mrt->mroute_do_assert && 2040 + if (true_vifi >= 0 && READ_ONCE(mrt->mroute_do_assert) && 2041 2041 /* pimsm uses asserts, when switching from RPT to SPT, 2042 2042 * so that we cannot check that packet arrived on an oif. 2043 2043 * It is bad, but otherwise we would need to move pretty 2044 2044 * large chunk of pimd to kernel. Ough... --ANK 2045 2045 */ 2046 - (mrt->mroute_do_pim || 2046 + (READ_ONCE(mrt->mroute_do_pim) || 2047 2047 c->_c.mfc_un.res.ttls[true_vifi] < 255) && 2048 2048 time_after(jiffies, 2049 2049 c->_c.mfc_un.res.last_assert + 2050 2050 MFC_ASSERT_THRESH)) { 2051 2051 c->_c.mfc_un.res.last_assert = jiffies; 2052 2052 ipmr_cache_report(mrt, skb, true_vifi, IGMPMSG_WRONGVIF); 2053 - if (mrt->mroute_do_wrvifwhole) 2053 + if (READ_ONCE(mrt->mroute_do_wrvifwhole)) 2054 2054 ipmr_cache_report(mrt, skb, true_vifi, 2055 2055 IGMPMSG_WRVIFWHOLE); 2056 2056 } ··· 2358 2358 mrt = ipmr_rt_fib_lookup(net, skb); 2359 2359 if (IS_ERR(mrt)) 2360 2360 goto drop; 2361 - if (!mrt->mroute_do_pim || 2361 + if (!READ_ONCE(mrt->mroute_do_pim) || 2362 2362 pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER) 2363 2363 goto drop; 2364 2364