]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ndisc: use RCU protection in ndisc_alloc_skb()
authorEric Dumazet <edumazet@google.com>
Fri, 7 Feb 2025 13:58:34 +0000 (13:58 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Mar 2025 11:47:21 +0000 (12:47 +0100)
[ Upstream commit 628e6d18930bbd21f2d4562228afe27694f66da9 ]

ndisc_alloc_skb() can be called without RTNL or RCU being held.

Add RCU protection to avoid possible UAF.

Fixes: de09334b9326 ("ndisc: Introduce ndisc_alloc_skb() helper.")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250207135841.1948589-3-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/ipv6/ndisc.c

index c0a5552733177c02a1d94466106cca4e718fab60..2361f4af49e8fe50a4fa248a2a6a7adeaf625cf5 100644 (file)
@@ -417,15 +417,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
 {
        int hlen = LL_RESERVED_SPACE(dev);
        int tlen = dev->needed_tailroom;
-       struct sock *sk = dev_net(dev)->ipv6.ndisc_sk;
        struct sk_buff *skb;
 
        skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC);
-       if (!skb) {
-               ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n",
-                         __func__);
+       if (!skb)
                return NULL;
-       }
 
        skb->protocol = htons(ETH_P_IPV6);
        skb->dev = dev;
@@ -436,7 +432,9 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
        /* Manually assign socket ownership as we avoid calling
         * sock_alloc_send_pskb() to bypass wmem buffer limits
         */
-       skb_set_owner_w(skb, sk);
+       rcu_read_lock();
+       skb_set_owner_w(skb, dev_net_rcu(dev)->ipv6.ndisc_sk);
+       rcu_read_unlock();
 
        return skb;
 }