lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250915012914.361334-1-lizhi.xu@windriver.com>
Date: Mon, 15 Sep 2025 09:29:13 +0800
From: Lizhi Xu <lizhi.xu@...driver.com>
To: <syzbot+205ef33a3b636b4181fb@...kaller.appspotmail.com>
CC: <gregkh@...uxfoundation.org>, <linux-kernel@...r.kernel.org>,
        <linux-usb@...r.kernel.org>, <syzkaller-bugs@...glegroups.com>
Subject: [PATCH] usb: mon: Make mon_bus::lock a raw spinlock

Interrupts are disabled before entering usb_hcd_giveback_urb().
A spinlock_t becomes a sleeping lock on PREEMPT_RT, so it cannot be
acquired with disabled interrupts.

Make mon_bus::lock a raw spinlock so it can be used with interrupts disabled.

syz reported:
BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
CPU: 1 UID: 0 PID: 45 Comm: kworker/1:1 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
Workqueue: usb_hub_wq hub_event
Call Trace:
 <TASK>
 dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
 __might_resched+0x44b/0x5d0 kernel/sched/core.c:8957
 rt_spin_lock+0xc7/0x2c0 kernel/locking/spinlock_rt.c:57
 spin_lock include/linux/spinlock_rt.h:44 [inline]
 mon_bus_complete drivers/usb/mon/mon_main.c:134 [inline]
 mon_complete+0x5c/0x200 drivers/usb/mon/mon_main.c:147
 usbmon_urb_complete include/linux/usb/hcd.h:738 [inline]
 __usb_hcd_giveback_urb+0x254/0x5e0 drivers/usb/core/hcd.c:1647
 vhci_urb_enqueue+0xb4f/0xe70 drivers/usb/usbip/vhci_hcd.c:818

Reported-by: syzbot+205ef33a3b636b4181fb@...kaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=205ef33a3b636b4181fb
Signed-off-by: Lizhi Xu <lizhi.xu@...driver.com>
---
 drivers/usb/mon/mon_main.c | 24 +++++++++---------------
 drivers/usb/mon/mon_text.c |  6 +++---
 drivers/usb/mon/usb_mon.h  |  2 +-
 3 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
index af852d53aac6..83d19b769d84 100644
--- a/drivers/usb/mon/mon_main.c
+++ b/drivers/usb/mon/mon_main.c
@@ -38,7 +38,7 @@ void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r)
 	unsigned long flags;
 	struct list_head *p;
 
-	spin_lock_irqsave(&mbus->lock, flags);
+	raw_spin_lock_irqsave(&mbus->lock, flags);
 	if (mbus->nreaders == 0) {
 		if (mbus == &mon_bus0) {
 			list_for_each (p, &mon_buses) {
@@ -52,7 +52,7 @@ void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r)
 	}
 	mbus->nreaders++;
 	list_add_tail(&r->r_link, &mbus->r_list);
-	spin_unlock_irqrestore(&mbus->lock, flags);
+	raw_spin_unlock_irqrestore(&mbus->lock, flags);
 
 	kref_get(&mbus->ref);
 }
@@ -66,12 +66,12 @@ void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&mbus->lock, flags);
+	raw_spin_lock_irqsave(&mbus->lock, flags);
 	list_del(&r->r_link);
 	--mbus->nreaders;
 	if (mbus->nreaders == 0)
 		mon_stop(mbus);
-	spin_unlock_irqrestore(&mbus->lock, flags);
+	raw_spin_unlock_irqrestore(&mbus->lock, flags);
 
 	kref_put(&mbus->ref, mon_bus_drop);
 }
@@ -80,14 +80,12 @@ void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r)
  */
 static void mon_bus_submit(struct mon_bus *mbus, struct urb *urb)
 {
-	unsigned long flags;
 	struct mon_reader *r;
 
-	spin_lock_irqsave(&mbus->lock, flags);
+	guard(raw_spinlock_irqsave)(&mbus->lock);
 	mbus->cnt_events++;
 	list_for_each_entry(r, &mbus->r_list, r_link)
 		r->rnf_submit(r->r_data, urb);
-	spin_unlock_irqrestore(&mbus->lock, flags);
 }
 
 static void mon_submit(struct usb_bus *ubus, struct urb *urb)
@@ -104,14 +102,12 @@ static void mon_submit(struct usb_bus *ubus, struct urb *urb)
  */
 static void mon_bus_submit_error(struct mon_bus *mbus, struct urb *urb, int error)
 {
-	unsigned long flags;
 	struct mon_reader *r;
 
-	spin_lock_irqsave(&mbus->lock, flags);
+	guard(raw_spinlock_irqsave)(&mbus->lock);
 	mbus->cnt_events++;
 	list_for_each_entry(r, &mbus->r_list, r_link)
 		r->rnf_error(r->r_data, urb, error);
-	spin_unlock_irqrestore(&mbus->lock, flags);
 }
 
 static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error)
@@ -128,14 +124,12 @@ static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error)
  */
 static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb, int status)
 {
-	unsigned long flags;
 	struct mon_reader *r;
 
-	spin_lock_irqsave(&mbus->lock, flags);
+	guard(raw_spinlock_irqsave)(&mbus->lock);
 	mbus->cnt_events++;
 	list_for_each_entry(r, &mbus->r_list, r_link)
 		r->rnf_complete(r->r_data, urb, status);
-	spin_unlock_irqrestore(&mbus->lock, flags);
 }
 
 static void mon_complete(struct usb_bus *ubus, struct urb *urb, int status)
@@ -277,7 +271,7 @@ static void mon_bus_init(struct usb_bus *ubus)
 	if (mbus == NULL)
 		goto err_alloc;
 	kref_init(&mbus->ref);
-	spin_lock_init(&mbus->lock);
+	raw_spin_lock_init(&mbus->lock);
 	INIT_LIST_HEAD(&mbus->r_list);
 
 	/*
@@ -304,7 +298,7 @@ static void mon_bus0_init(void)
 	struct mon_bus *mbus = &mon_bus0;
 
 	kref_init(&mbus->ref);
-	spin_lock_init(&mbus->lock);
+	raw_spin_lock_init(&mbus->lock);
 	INIT_LIST_HEAD(&mbus->r_list);
 
 	mbus->text_inited = mon_text_add(mbus, NULL);
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 68b9b2b41189..b482c610dad1 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -307,15 +307,15 @@ static struct mon_event_text *mon_text_fetch(struct mon_reader_text *rp,
 	struct list_head *p;
 	unsigned long flags;
 
-	spin_lock_irqsave(&mbus->lock, flags);
+	raw_spin_lock_irqsave(&mbus->lock, flags);
 	if (list_empty(&rp->e_list)) {
-		spin_unlock_irqrestore(&mbus->lock, flags);
+		raw_spin_unlock_irqrestore(&mbus->lock, flags);
 		return NULL;
 	}
 	p = rp->e_list.next;
 	list_del(p);
 	--rp->nevents;
-	spin_unlock_irqrestore(&mbus->lock, flags);
+	raw_spin_unlock_irqrestore(&mbus->lock, flags);
 	return list_entry(p, struct mon_event_text, e_link);
 }
 
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h
index aa64efaba366..d2a342feaad3 100644
--- a/drivers/usb/mon/usb_mon.h
+++ b/drivers/usb/mon/usb_mon.h
@@ -17,7 +17,7 @@
 
 struct mon_bus {
 	struct list_head bus_link;
-	spinlock_t lock;
+	raw_spinlock_t lock;
 	struct usb_bus *u_bus;
 
 	int text_inited;
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ