lkml.org 
[lkml]   [2022]   [May]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.17 096/140] mld: respect RCU rules in ip6_mc_source() and ip6_mc_msfilter()
    Date
    From: Eric Dumazet <edumazet@google.com>

    commit a9384a4c1d250cb40cebf50e41459426d160b08e upstream.

    Whenever RCU protected list replaces an object,
    the pointer to the new object needs to be updated
    _before_ the call to kfree_rcu() or call_rcu()

    Also ip6_mc_msfilter() needs to update the pointer
    before releasing the mc_lock mutex.

    Note that linux-5.13 was supporting kfree_rcu(NULL, rcu),
    so this fix does not need the conditional test I was
    forced to use in the equivalent patch for IPv4.

    Fixes: 882ba1f73c06 ("mld: convert ipv6_mc_socklist->sflist to RCU")
    Signed-off-by: Eric Dumazet <edumazet@google.com>
    Cc: Taehee Yoo <ap420073@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/ipv6/mcast.c | 8 ++++----
    1 file changed, 4 insertions(+), 4 deletions(-)

    --- a/net/ipv6/mcast.c
    +++ b/net/ipv6/mcast.c
    @@ -460,10 +460,10 @@ int ip6_mc_source(int add, int omode, st
    newpsl->sl_addr[i] = psl->sl_addr[i];
    atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
    &sk->sk_omem_alloc);
    - kfree_rcu(psl, rcu);
    }
    + rcu_assign_pointer(pmc->sflist, newpsl);
    + kfree_rcu(psl, rcu);
    psl = newpsl;
    - rcu_assign_pointer(pmc->sflist, psl);
    }
    rv = 1; /* > 0 for insert logic below if sl_count is 0 */
    for (i = 0; i < psl->sl_count; i++) {
    @@ -565,12 +565,12 @@ int ip6_mc_msfilter(struct sock *sk, str
    psl->sl_count, psl->sl_addr, 0);
    atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
    &sk->sk_omem_alloc);
    - kfree_rcu(psl, rcu);
    } else {
    ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0);
    }
    - mutex_unlock(&idev->mc_lock);
    rcu_assign_pointer(pmc->sflist, newpsl);
    + mutex_unlock(&idev->mc_lock);
    + kfree_rcu(psl, rcu);
    pmc->sfmode = gsf->gf_fmode;
    err = 0;
    done:

    \
     
     \ /
      Last update: 2022-05-10 16:27    [W:4.194 / U:0.256 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site