[RFC PATCH] media: gspca: destroy input URB after failed stream start

From: Wang Xiong

Date: Fri Oct 16 2026 - 00:19:39 EST


When a video URB submission fails, gspca_init_transfer() calls
gspca_stream_off(). That helper can recreate an input URB after switching
to alternate setting zero. The retry or error exit then creates another
input URB and overwrites the sole int_urb pointer.

The earlier URB can remain active and resubmit itself from int_irq(),
although normal input teardown only cancels the stored URB. Its callback
can then access device state after that state has been released.

Destroy the input URB recreated by gspca_stream_off() before retrying or
taking the error exit. The final input creation then owns the only input
URB. The destroy helper synchronously waits for the callback before
freeing its resources. Normal stream shutdown keeps its input behavior.

Signed-off-by: Wang Xiong <20221010117@xxxxxxxxxxxxxxx>
---

Notes (mail-human-signoff-20261016):
Selected diagnostic lines from the archived report (excerpts):
gspca_main: usb_submit_urb alt 1 err -2
BUG: KASAN: slab-use-after-free in int_irq
Read of size 8

This RFC addresses failed-start input-URB ownership. It does not claim
to repair every saved gspca fault. The precise sequence leading to the
archived crash has not been reproduced.

This candidate concerns input-URB ownership on failed start. The stop0
path can drop usb_lock, so disconnect and power-management interactions
still need review.

No introducing commit is attributed by a Fixes tag in this RFC.

Build-tested with GCC 14.2.0 and binutils 2.44 on x86_64, against
base 03e2778d1f11de9260543f969e9e888a1c2bf830 (Linux 7.1.2).
The baseline and candidate bzImage/modules builds passed. The
candidate driver was enabled as a module in a minimal configuration.
The original crash configuration and runtime repair were not tested.

drivers/media/usb/gspca/gspca.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index f3d3f441c8510f391008bf2b54c1ee344ee85653..cd3dc70586a079e5240eab6413c0c384625852a5 100644
--- a/drivers/media/usb/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -866,6 +866,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
/* something when wrong
* stop the webcam and free the transfer resources */
gspca_stream_off(gspca_dev);
+ /* The retry or exit path creates its own input URB. */
+ gspca_input_destroy_urb(gspca_dev);
if (ret != -ENOSPC) {
pr_err("usb_submit_urb alt %d err %d\n",
gspca_dev->alt, ret);

base-commit: 03e2778d1f11de9260543f969e9e888a1c2bf830
--
2.47.3