lkml.org 
[lkml]   [2022]   [Jul]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.18 062/158] igmp: Fix data-races around sysctl_igmp_llm_reports.
    Date
    From: Kuniyuki Iwashima <kuniyu@amazon.com>

    [ Upstream commit f6da2267e71106474fbc0943dc24928b9cb79119 ]

    While reading sysctl_igmp_llm_reports, it can be changed concurrently.
    Thus, we need to add READ_ONCE() to its readers.

    This test can be packed into a helper, so such changes will be in the
    follow-up series after net is merged into net-next.

    if (ipv4_is_local_multicast(pmc->multiaddr) &&
    !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))

    Fixes: df2cf4a78e48 ("IGMP: Inhibit reports for local multicast groups")
    Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/ipv4/igmp.c | 21 +++++++++++++--------
    1 file changed, 13 insertions(+), 8 deletions(-)

    diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
    index 1d9e6d5e9a76..0bde3774505f 100644
    --- a/net/ipv4/igmp.c
    +++ b/net/ipv4/igmp.c
    @@ -467,7 +467,8 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,

    if (pmc->multiaddr == IGMP_ALL_HOSTS)
    return skb;
    - if (ipv4_is_local_multicast(pmc->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports)
    + if (ipv4_is_local_multicast(pmc->multiaddr) &&
    + !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
    return skb;

    mtu = READ_ONCE(dev->mtu);
    @@ -593,7 +594,7 @@ static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc)
    if (pmc->multiaddr == IGMP_ALL_HOSTS)
    continue;
    if (ipv4_is_local_multicast(pmc->multiaddr) &&
    - !net->ipv4.sysctl_igmp_llm_reports)
    + !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
    continue;
    spin_lock_bh(&pmc->lock);
    if (pmc->sfcount[MCAST_EXCLUDE])
    @@ -736,7 +737,8 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
    if (type == IGMPV3_HOST_MEMBERSHIP_REPORT)
    return igmpv3_send_report(in_dev, pmc);

    - if (ipv4_is_local_multicast(group) && !net->ipv4.sysctl_igmp_llm_reports)
    + if (ipv4_is_local_multicast(group) &&
    + !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
    return 0;

    if (type == IGMP_HOST_LEAVE_MESSAGE)
    @@ -920,7 +922,8 @@ static bool igmp_heard_report(struct in_device *in_dev, __be32 group)

    if (group == IGMP_ALL_HOSTS)
    return false;
    - if (ipv4_is_local_multicast(group) && !net->ipv4.sysctl_igmp_llm_reports)
    + if (ipv4_is_local_multicast(group) &&
    + !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
    return false;

    rcu_read_lock();
    @@ -1045,7 +1048,7 @@ static bool igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
    if (im->multiaddr == IGMP_ALL_HOSTS)
    continue;
    if (ipv4_is_local_multicast(im->multiaddr) &&
    - !net->ipv4.sysctl_igmp_llm_reports)
    + !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
    continue;
    spin_lock_bh(&im->lock);
    if (im->tm_running)
    @@ -1296,7 +1299,8 @@ static void __igmp_group_dropped(struct ip_mc_list *im, gfp_t gfp)
    #ifdef CONFIG_IP_MULTICAST
    if (im->multiaddr == IGMP_ALL_HOSTS)
    return;
    - if (ipv4_is_local_multicast(im->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports)
    + if (ipv4_is_local_multicast(im->multiaddr) &&
    + !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
    return;

    reporter = im->reporter;
    @@ -1338,7 +1342,8 @@ static void igmp_group_added(struct ip_mc_list *im)
    #ifdef CONFIG_IP_MULTICAST
    if (im->multiaddr == IGMP_ALL_HOSTS)
    return;
    - if (ipv4_is_local_multicast(im->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports)
    + if (ipv4_is_local_multicast(im->multiaddr) &&
    + !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
    return;

    if (in_dev->dead)
    @@ -1642,7 +1647,7 @@ static void ip_mc_rejoin_groups(struct in_device *in_dev)
    if (im->multiaddr == IGMP_ALL_HOSTS)
    continue;
    if (ipv4_is_local_multicast(im->multiaddr) &&
    - !net->ipv4.sysctl_igmp_llm_reports)
    + !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
    continue;

    /* a failover is happening and switches
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-07-27 19:41    [W:2.892 / U:0.088 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site