From: Jiayuan Chen <jiayuan.chen@linux.dev>
To: netdev@vger.kernel.org
Cc: Jiayuan Chen <jiayuan.chen@shopee.com>,
syzbot+afbcf622635e98bf40d2@syzkaller.appspotmail.com,
Jiayuan Chen <jiayuan.chen@linux.dev>,
"David S. Miller" <davem@davemloft.net>,
David Ahern <dsahern@kernel.org>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>, Taehee Yoo <ap420073@gmail.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH net v1] net/ipv6: mcast: fix circular locking dependency in __ipv6_dev_mc_inc()
Date: Tue, 17 Mar 2026 19:12:07 +0800 [thread overview]
Message-ID: <20260317111208.62667-1-jiayuan.chen@linux.dev> (raw)
From: Jiayuan Chen <jiayuan.chen@shopee.com>
syzbot reported a possible circular locking dependency:
fs_reclaim --> sk_lock-AF_INET6 --> &idev->mc_lock
CPU0 CPU1
---- ----
lock(&idev->mc_lock)
lock(sk_lock-AF_INET6)
lock(&idev->mc_lock) // blocked
kzalloc(GFP_KERNEL)
fs_reclaim
...nbd I/O...
sk_lock-AF_INET6 // blocked -> DEADLOCK
__ipv6_dev_mc_inc() does GFP_KERNEL allocation inside mc_lock via
mca_alloc(). This can enter memory reclaim, which through nbd block
I/O may need sk_lock-AF_INET6. But sk_lock -> mc_lock already exists
via setsockopt -> __ipv6_sock_mc_join, so we have a deadlock.
Before commit 63ed8de4be81 ("mld: add mc_lock for protecting
per-interface mld data"), only RTNL was held during the allocation.
The lock ordering was always RTNL -> sk_lock (the nbd path doesn't
involve RTNL), so there was no circular dependency.
Split mca_alloc() into mca_alloc() + mca_init(): mca_alloc() does the
GFP_KERNEL allocation before mc_lock, mca_init() initializes under
mc_lock. If the address already exists, the pre-allocated memory is
simply freed. Also move inet6_ifmcaddr_notify() outside mc_lock since
it also does GFP_KERNEL allocation.
Fixes: 63ed8de4be81 ("mld: add mc_lock for protecting per-interface mld data")
Reported-by: syzbot+afbcf622635e98bf40d2@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/69b7dc76.050a0220.248e02.0113.GAE@google.com/T/
Cc: Jiayuan Chen <jiayuan.chen@linux.dev>
Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com>
---
net/ipv6/mcast.c | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 3330adcf26db..2dfa7ed54d17 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -860,18 +860,16 @@ static void ma_put(struct ifmcaddr6 *mc)
}
}
-static struct ifmcaddr6 *mca_alloc(struct inet6_dev *idev,
- const struct in6_addr *addr,
- unsigned int mode)
+static struct ifmcaddr6 *mca_alloc(void)
{
- struct ifmcaddr6 *mc;
+ return kzalloc_obj(struct ifmcaddr6);
+}
+static void mca_init(struct inet6_dev *idev, const struct in6_addr *addr,
+ unsigned int mode, struct ifmcaddr6 *mc)
+{
mc_assert_locked(idev);
- mc = kzalloc_obj(*mc);
- if (!mc)
- return NULL;
-
INIT_DELAYED_WORK(&mc->mca_work, mld_mca_work);
mc->mca_addr = *addr;
@@ -887,8 +885,6 @@ static struct ifmcaddr6 *mca_alloc(struct inet6_dev *idev,
if (ipv6_addr_is_ll_all_nodes(&mc->mca_addr) ||
IPV6_ADDR_MC_SCOPE(&mc->mca_addr) < IPV6_ADDR_SCOPE_LINKLOCAL)
mc->mca_flags |= MAF_NOREPORT;
-
- return mc;
}
static void inet6_ifmcaddr_notify(struct net_device *dev,
@@ -932,6 +928,7 @@ static void inet6_ifmcaddr_notify(struct net_device *dev,
static int __ipv6_dev_mc_inc(struct net_device *dev,
const struct in6_addr *addr, unsigned int mode)
{
+ struct ifmcaddr6 *mc_alloced;
struct inet6_dev *idev;
struct ifmcaddr6 *mc;
@@ -940,10 +937,17 @@ static int __ipv6_dev_mc_inc(struct net_device *dev,
if (!idev)
return -EINVAL;
+ mc_alloced = mca_alloc();
+ if (!mc_alloced) {
+ in6_dev_put(idev);
+ return -ENOMEM;
+ }
+
mutex_lock(&idev->mc_lock);
if (READ_ONCE(idev->dead)) {
mutex_unlock(&idev->mc_lock);
+ kfree(mc_alloced);
in6_dev_put(idev);
return -ENODEV;
}
@@ -953,26 +957,24 @@ static int __ipv6_dev_mc_inc(struct net_device *dev,
mc->mca_users++;
ip6_mc_add_src(idev, &mc->mca_addr, mode, 0, NULL, 0);
mutex_unlock(&idev->mc_lock);
+ kfree(mc_alloced);
in6_dev_put(idev);
return 0;
}
}
- mc = mca_alloc(idev, addr, mode);
- if (!mc) {
- mutex_unlock(&idev->mc_lock);
- in6_dev_put(idev);
- return -ENOMEM;
- }
+ mca_init(idev, addr, mode, mc_alloced);
+ mc = mc_alloced;
rcu_assign_pointer(mc->next, idev->mc_list);
rcu_assign_pointer(idev->mc_list, mc);
mld_del_delrec(idev, mc);
igmp6_group_added(mc);
- inet6_ifmcaddr_notify(dev, mc, RTM_NEWMULTICAST);
mutex_unlock(&idev->mc_lock);
+ inet6_ifmcaddr_notify(dev, mc, RTM_NEWMULTICAST);
+
return 0;
}
--
2.43.0
next reply other threads:[~2026-03-17 11:12 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-17 11:12 Jiayuan Chen [this message]
2026-03-19 1:15 ` [PATCH net v1] net/ipv6: mcast: fix circular locking dependency in __ipv6_dev_mc_inc() Jakub Kicinski
2026-03-19 3:04 ` Jiayuan Chen
2026-03-19 3:26 ` Jakub Kicinski
2026-03-19 4:12 ` Jiayuan Chen
2026-03-19 12:44 ` Paolo Abeni
2026-03-19 15:36 ` Wouter Verhelst
2026-03-23 6:54 ` Kuniyuki Iwashima
2026-03-19 12:33 ` [net,v1] " Paolo Abeni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260317111208.62667-1-jiayuan.chen@linux.dev \
--to=jiayuan.chen@linux.dev \
--cc=ap420073@gmail.com \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jiayuan.chen@shopee.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=syzbot+afbcf622635e98bf40d2@syzkaller.appspotmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.