From: Khawar Ahemad <ahemadkhawar123@gmail.com>
To: bpf@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, magnus.karlsson@intel.com,
maciej.fijalkowski@intel.com, sdf@fomichev.me, ast@kernel.org,
daniel@iogearbox.net, hawk@kernel.org, john.fastabend@gmail.com,
kuba@kernel.org, pabeni@redhat.com, edumazet@google.com,
horms@kernel.org,
syzbot+aa48b5fe7bfda62d1682@syzkaller.appspotmail.com
Subject: [PATCH bpf-next v6] xsk: Fix circular locking dependency between &net->xdp.lock, &xs->mutex, and netdev_lock_ops
Date: Tue, 15 Sep 2026 13:40:23 +0530 [thread overview]
Message-ID: <20260915081023.7433-1-ahemadkhawar123@gmail.com> (raw)
syzbot reported a circular locking dependency involving &net->xdp.lock,
&port->pnodes_lock, netdev_lock_ops(), and &xs->mutex:
-> #3 (&net->xdp.lock):
xsk_notifier+0x3d/0x2c0 net/xdp/xsk.c:2106
ipvlan_device_event+0x310/0x4e0 drivers/net/ipvlan/ipvlan_main.c:834
unregister_netdevice_many_notify+0x808/0x18b0 net/core/dev.c:12518
-> #2 (&port->pnodes_lock):
ipvlan_device_event+0x85/0x4e0 drivers/net/ipvlan/ipvlan_main.c:795
notifier_call_chain+0xb5/0x410 kernel/notifier.c:85
-> #1 (&dev_instance_lock_key / netdev_lock_ops):
netdev_lock_ops include/net/netdev_lock.h:42 [inline]
xsk_bind+0x331/0x11d0 net/xdp/xsk.c:1627
-> #0 (&xs->mutex):
xsk_diag_fill net/xdp/xsk_diag.c:113 [inline]
xsk_diag_dump+0x2e0/0x4e0 net/xdp/xsk_diag.c:166
The cycle exists through the following dependency chain:
1. xsk_bind() acquired netdev_lock_ops() while holding &xs->mutex (#1).
2. Device unregistration in ipvlan_device_event() acquired
&port->pnodes_lock (#2) and called xsk_notifier(), which acquired
&net->xdp.lock (#3).
3. Both xsk_diag_dump() and xsk_notifier() acquire &xs->mutex while
holding &net->xdp.lock (#0).
Break the circular dependency at its source in xsk_bind() by acquiring
netdev_lock_ops() before &xs->mutex. To preserve the exact errno precedence
(-EBUSY vs -ENODEV) without requiring the mutex to read sxdp_ifindex, we
look up the net_device first. If the device exists, we lock netdev_lock_ops()
and then &xs->mutex, evaluating the socket state safely. The cleanup path
is adjusted to unlock in reverse order, ensuring device references are
correctly maintained or dropped.
This single lock reordering fully eliminates the &xs->mutex ->
netdev_lock_ops() edge, resolving the 4-lock cycle without introducing
concurrency regressions in the diagnostic dump or notifier paths.
Fixes: 975b11ae9077 ("xsk: add socket allocate, create and bind")
Reported-by: syzbot+aa48b5fe7bfda62d1682@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=aa48b5fe7bfda62d1682
Signed-off-by: Khawar Ahemad <ahemadkhawar123@gmail.com>
---
v5 -> v6:
- Abandon the two-phase xsk_notifier() and xsk_diag_dump() decoupling from
v3-v5, which introduced a Use-After-Free during concurrent xsk_release(),
and an O(N^2) list traversal complexity in xsk_diag_dump().
- Break the cycle at its root in xsk_bind() by acquiring netdev_lock_ops()
before &xs->mutex, fully removing the &xs->mutex -> netdev_lock_ops edge.
- Look up the net_device before locking &xs->mutex to preserve the original
-EBUSY vs -ENODEV errno precedence without any behavioural change.
- Link to v5: https://lore.kernel.org/bpf/20260902041257.58374-1-ahemadkhawar123@gmail.com/
v4 -> v5:
- Rebase cleanly on latest bpf-next master.
- Link to v4: https://lore.kernel.org/bpf/20260826174744.3394-1-ahemadkhawar123@gmail.com/
v3 -> v4:
- Rebase cleanly on latest bpf-next master to resolve merge conflict.
- Update commit message to accurately describe the full 4-lock dependency
chain (&net->xdp.lock, &port->pnodes_lock, netdev_lock_ops, &xs->mutex).
- Link to v3: https://lore.kernel.org/bpf/20260826173019.2917-1-ahemadkhawar123@gmail.com/
v2 -> v3:
- Fix direct AB-BA lock inversion in xsk_notifier() by performing device
queue sweeps via xsk_get_pool_from_qid() outside &net->xdp.lock.
- Eliminate &net->xdp.lock -> &xs->mutex in xsk_diag_dump() by taking a
temporary socket reference and releasing the lock before xsk_diag_fill().
- Link to v2: https://lore.kernel.org/bpf/20260826162110.99879-1-ahemadkhawar123@gmail.com/
v1 -> v2:
- Avoid reordering locks in xsk_bind() to preserve errno precedence.
- Link to v1: https://lore.kernel.org/bpf/20260825152152.86092-1-ahemadkhawar123@gmail.com/
net/xdp/xsk.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 7855ee09c4..0a4106e98b 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -1612,20 +1612,22 @@ static int xsk_bind(struct socket *sock, struct sockaddr_unsized *addr, int addr
return -EINVAL;
rtnl_lock();
+
+ dev = dev_get_by_index(sock_net(sk), sxdp->sxdp_ifindex);
+ if (dev)
+ netdev_lock_ops(dev);
+
mutex_lock(&xs->mutex);
if (xs->state != XSK_READY) {
err = -EBUSY;
goto out_release;
}
- dev = dev_get_by_index(sock_net(sk), sxdp->sxdp_ifindex);
if (!dev) {
err = -ENODEV;
goto out_release;
}
- netdev_lock_ops(dev);
-
if (!xs->rx && !xs->tx) {
err = -EINVAL;
goto out_unlock;
@@ -1762,18 +1764,20 @@ static int xsk_bind(struct socket *sock, struct sockaddr_unsized *addr, int addr
}
out_unlock:
- if (err) {
- dev_put(dev);
- } else {
+ if (!err) {
/* Matches smp_rmb() in bind() for shared umem
* sockets, and xsk_is_bound().
*/
smp_wmb();
WRITE_ONCE(xs->state, XSK_BOUND);
}
- netdev_unlock_ops(dev);
out_release:
mutex_unlock(&xs->mutex);
+ if (dev) {
+ netdev_unlock_ops(dev);
+ if (err)
+ dev_put(dev);
+ }
rtnl_unlock();
return err;
}
--
2.54.0 (Apple Git-157)
next reply other threads:[~2026-09-15 8:10 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-15 8:10 Khawar Ahemad [this message]
2026-09-15 8:46 ` bot+bpf-ci
2026-09-15 14:50 ` [syzbot ci] " syzbot ci
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=20260915081023.7433-1-ahemadkhawar123@gmail.com \
--to=ahemadkhawar123@gmail.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=edumazet@google.com \
--cc=hawk@kernel.org \
--cc=horms@kernel.org \
--cc=john.fastabend@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maciej.fijalkowski@intel.com \
--cc=magnus.karlsson@intel.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sdf@fomichev.me \
--cc=syzbot+aa48b5fe7bfda62d1682@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®