diff options
| author | Slawomir Stepien <sst@poczta.fm> | 2026-07-30 08:52:31 +0200 |
|---|---|---|
| committer | Johannes Berg <johannes.berg@intel.com> | 2026-08-02 18:23:27 +0200 |
| commit | 0e4532ec658606f76f62eb277e7a933919d36cbb (patch) | |
| tree | 01ce5232cc123f8f58b8a656c5d5c483e6c2bd13 /drivers | |
| parent | 927ee844c47ac2aef22c8f7a35f098ff576b398b (diff) | |
| download | linux-next-0e4532ec658606f76f62eb277e7a933919d36cbb.tar.gz linux-next-0e4532ec658606f76f62eb277e7a933919d36cbb.zip | |
wifi: zd1211rw: reject secondary interfaces to prevent conflicts
The zd1211rw driver is designed for single-function Wi-Fi dongles and
hardcodes its USB endpoints. When a malformed USB device exposes multiple
interfaces that match the driver's device ID, the driver blindly binds to
all of them.
During probe(), the driver calls usb_reset_device(), which iterates over
all interfaces and invokes the pre_reset() callback for each bound
interface. Since multiple interfaces are bound to zd1211rw, pre_reset() is
called sequentially for each instance, acquiring their respective
&mac->chip.mutex. Because all instances initialize their mutexes with the
same lock class, lockdep detects a task acquiring a lock of the same class
it already holds and flags it as a possible recursive deadlock:
WARNING: possible recursive locking detected
kworker/0:1/11 is trying to acquire lock:
ffff88810371dde0 (&chip->mutex){+.+.}-{4:4}, at:
zd_chip_disable_rxtx+0x20/0x50
drivers/net/wireless/zydas/zd1211rw/zd_chip.c:1465
but task is already holding lock:
ffff8881138ddde0 (&chip->mutex){+.+.}-{4:4}, at: pre_reset+0x28c/0x380
drivers/net/wireless/zydas/zd1211rw/zd_usb.c:1505
Fix this by explicitly rejecting secondary interfaces (bInterfaceNumber !=
0) during probe(). This ensures that only a single instance of the driver
binds to the device, eliminating the recursive locking scenario.
Fixes: e85d0918b54f ("[PATCH] ZyDAS ZD1211 USB-WLAN driver")
Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: syzbot+0ec3d1a6cf1fbe79c153@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=0ec3d1a6cf1fbe79c153
Link: https://syzkaller.appspot.com/ai_job?id=00724ef7-fd77-4cde-9779-895b8f63c2f6
Signed-off-by: Slawomir Stepien <sst@poczta.fm>
Link: https://patch.msgid.link/20260730065231.1644030-1-sst@poczta.fm
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/wireless/zydas/zd1211rw/zd_usb.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c index 966d8ccb0dbc..98102c663434 100644 --- a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c @@ -1353,6 +1353,14 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id) struct zd_usb *usb; struct ieee80211_hw *hw = NULL; + /* + * ZD1211 devices are single-function. Reject secondary interfaces + * to prevent multiple instances from conflicting on hardcoded endpoints + * and triggering recursive locking warnings. + */ + if (intf->cur_altsetting->desc.bInterfaceNumber != 0) + return -ENODEV; + print_id(udev); if (id->driver_info & DEVICE_INSTALLER) |
