public inbox for linux-usb@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] usb: gadget: raw_gadget: fix double free in raw_release
@ 2026-03-26  8:22 cuiyudong
  2026-03-26  8:44 ` Greg Kroah-Hartman
  0 siblings, 1 reply; 4+ messages in thread
From: cuiyudong @ 2026-03-26  8:22 UTC (permalink / raw)
  To: Andrey Konovalov, Greg Kroah-Hartman
  Cc: Kees Cook, Gopi Krishna Menon, linux-usb, linux-kernel

In raw_release(), when unregister == true, there are two kref_put() calls:
1. Inside the unregister block (extra)
2. At out_put label

The refcount increments are:
- 1 ref from dev_new() in raw_open()
- 1 ref from kref_get() in raw_ioctl_run()

Total: 2 references.

The original code performed 3 kref_put() operations, which causes the refcount
to drop below zero and leads to a double free in dev_free().

Remove the extra kref_put() inside the unregister block to balance the
reference counter correctly.

Since the extra kref_put() triggers an immediate use-after-free condition
on the dev structure, KASAN reports a double-free instead of a refcount warning.

BUG: KASAN: double-free in dev_free+0x424/0x740
Fixes: f2c2e717642c ("usb: gadget: add raw-gadget interface")
Reported-by: syzbot+25612fe5ab3dcafc3aab@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/69c401ad.a70a0220.23629d.0000.GAE@google.com/
Signed-off-by: cuiyudong <cuiyudong@kylinos.cn>
---
 drivers/usb/gadget/legacy/raw_gadget.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c
index 4febf8dac7ca..a1fd3fdf1323 100644
--- a/drivers/usb/gadget/legacy/raw_gadget.c
+++ b/drivers/usb/gadget/legacy/raw_gadget.c
@@ -465,12 +465,10 @@ static int raw_release(struct inode *inode, struct file *fd)
 			dev_err(dev->dev,
 				"usb_gadget_unregister_driver() failed with %d\n",
 				ret);
-		/* Matches kref_get() in raw_ioctl_run(). */
-		kref_put(&dev->count, dev_free);
 	}
 
 out_put:
-	/* Matches dev_new() in raw_open(). */
+	/* Matches dev_new() in raw_open() and kref_get() in raw_ioctl_run(). */
 	kref_put(&dev->count, dev_free);
 	return ret;
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread
* [PATCH v2] usb: gadget: raw_gadget: fix double free in raw_release
@ 2026-03-26  9:02 cuiyudong
  2026-03-26 10:18 ` Andrey Konovalov
  0 siblings, 1 reply; 4+ messages in thread
From: cuiyudong @ 2026-03-26  9:02 UTC (permalink / raw)
  To: Andrey Konovalov, Greg Kroah-Hartman
  Cc: Kees Cook, Gopi Krishna Menon, linux-usb, linux-kernel

In raw_release(), when unregister == true, there are two kref_put() calls:
1. Inside the unregister block (extra)
2. At out_put label

The refcount increments are:
- 1 ref from dev_new() in raw_open()
- 1 ref from kref_get() in raw_ioctl_run()

Total: 2 references.

The original code performed 3 kref_put() operations, which causes the refcount
to drop below zero and leads to a double free in dev_free().

Remove the extra kref_put() inside the unregister block to balance the
reference counter correctly.

Since the extra kref_put() triggers an immediate use-after-free condition
on the dev structure, KASAN reports a double-free instead of a refcount warning.

BUG: KASAN: double-free in dev_free+0x424/0x740
Fixes: f2c2e717642c ("usb: gadget: add raw-gadget interface")
Reported-by: syzbot+25612fe5ab3dcafc3aab@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/69c401ad.a70a0220.23629d.0000.GAE@google.com/
Signed-off-by: cuiyudong <cuiyudong@kylinos.cn>
---
Changes in v2:
- Removed Tested-by tag (syzbot did not test the patch)
- Expanded commit description to explain refcount imbalance and KASAN report
---
 drivers/usb/gadget/legacy/raw_gadget.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c
index 4febf8dac7ca..a1fd3fdf1323 100644
--- a/drivers/usb/gadget/legacy/raw_gadget.c
+++ b/drivers/usb/gadget/legacy/raw_gadget.c
@@ -465,12 +465,10 @@ static int raw_release(struct inode *inode, struct file *fd)
 			dev_err(dev->dev,
 				"usb_gadget_unregister_driver() failed with %d\n",
 				ret);
-		/* Matches kref_get() in raw_ioctl_run(). */
-		kref_put(&dev->count, dev_free);
 	}
 
 out_put:
-	/* Matches dev_new() in raw_open(). */
+	/* Matches dev_new() in raw_open() and kref_get() in raw_ioctl_run(). */
 	kref_put(&dev->count, dev_free);
 	return ret;
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-03-26 10:18 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-26  8:22 [PATCH v2] usb: gadget: raw_gadget: fix double free in raw_release cuiyudong
2026-03-26  8:44 ` Greg Kroah-Hartman
  -- strict thread matches above, loose matches on Subject: below --
2026-03-26  9:02 cuiyudong
2026-03-26 10:18 ` Andrey Konovalov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox