drivers/media/usb/uvc/uvc_video.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
Add safety checks to prevent kernel panic during the race window in
USB device disconnection.
The issue occurs in a specific timing window during hot-unplug:
- usb_disconnect() calls usb_disable_device() which sets
dev->actconfig->interface[i] to NULL
- But dev->actconfig is not yet set to NULL
- During this window, uvc_video_stop_streaming() calls usb_set_interface()
- This eventually calls usb_ifnum_to_if() which accesses the already
NULL interface[i]->altsetting, causing a kernel panic
logs:
[ 9518.891254] Call trace:
[ 9518.894817] usb_ifnum_to_if+0x34/0x50
[ 9518.899681] usb_set_interface+0x108/0x3c8
[ 9518.904898] uvc_video_stop_streaming+0x3c/0x90 [uvcvideo]
[ 9518.911500] uvc_stop_streaming+0x24/0x90 [uvcvideo]
[ 9518.917583] __vb2_queue_cancel+0x44/0x458 [videobuf2_common]
[ 9518.924444] vb2_core_streamoff+0x20/0xb8 [videobuf2_common]
[ 9518.931221] vb2_streamoff+0x18/0x60 [videobuf2_v4l2]
[ 9518.937390] uvc_queue_streamoff+0x30/0x50 [uvcvideo]
[ 9518.943557] uvc_ioctl_streamoff+0x40/0x68 [uvcvideo]
[ 9518.949724] v4l_streamoff+0x20/0x28
[ 9518.954415] __video_do_ioctl+0x17c/0x3e0
[ 9518.959540] video_usercopy+0x1d8/0x558
[ 9518.964490] video_ioctl2+0x14/0x1c
[ 9518.969094] v4l2_ioctl+0x3c/0x58
[ 9518.973526] do_vfs_ioctl+0x374/0x7b0
[ 9518.978304] ksys_ioctl+0x78/0xa8
[ 9518.982734] sys_ioctl+0xc/0x18
[ 9518.986991] __sys_trace_return+0x0/0x4
[ 9518.991943] Code: eb04005f 54000100 f9400040 91002042 (f9400003)
[ 9518.999153] ---[ end trace f7c7d3236806d9a4 ]---
The fix adds comprehensive NULL pointer validation:
- Check stream, stream->dev, stream->dev->udev, and stream->intf early
- Safely iterate through interfaces with proper NULL checks.
- Ensure config->interface[i] and its altsetting are valid before
access.
This prevents the crash by ensuring we don't access partially freed
USB interface structures during device removal.
Fixes: 571e70dbd421 ("media: uvcvideo: Split uvc_video_enable into two")
Signed-off-by: Jie Deng <dengjie03@kylinos.cn>
---
v2:
* Before the uvc driver calls usb_set_interface(), it first
checks whether the interface exists and is valid.
v1:
* Add a null pointer check in the usb_ifnum_to_if() function.
This plan cannot eliminate the root cause.
Link:https://lore.kernel.org/all/20251113114411.1410343-1-dengjie03@kylinos.cn/
---
drivers/media/usb/uvc/uvc_video.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 2094e059d7d3..30dd8ea8980e 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -2317,10 +2317,25 @@ int uvc_video_start_streaming(struct uvc_streaming *stream)
void uvc_video_stop_streaming(struct uvc_streaming *stream)
{
+ struct usb_host_config *config;
+ int i;
+
+ if (!stream || !stream->dev || !stream->dev->udev || !stream->intf)
+ goto cleanup_clock;
+
uvc_video_stop_transfer(stream, 1);
- if (stream->intf->num_altsetting > 1) {
- usb_set_interface(stream->dev->udev, stream->intfnum, 0);
+ config = stream->dev->udev->actconfig;
+ if (stream->intf->num_altsetting > 1 && config) {
+ /* Security Check: Check if the interface exists and is valid */
+ for (i = 0; i < config->desc.bNumInterfaces; i++) {
+ if (config->interface[i] &&
+ config->interface[i]->altsetting[0]
+ .desc.bInterfaceNumber == stream->intfnum) {
+ usb_set_interface(stream->dev->udev, stream->intfnum, 0);
+ break;
+ }
+ }
} else {
/*
* UVC doesn't specify how to inform a bulk-based device
@@ -2338,5 +2353,6 @@ void uvc_video_stop_streaming(struct uvc_streaming *stream)
usb_clear_halt(stream->dev->udev, pipe);
}
+cleanup_clock:
uvc_video_clock_cleanup(&stream->clock);
}
--
2.25.1
Hi Jie,
kernel test robot noticed the following build warnings:
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Jie-Deng/media-usb-uvc-Fix-NULL-pointer-dereference-during-USB-device-hot-unplug/20251122-152814
base: https://git.linuxtv.org/media-ci/media-pending.git master
patch link: https://lore.kernel.org/r/20251122072558.2604753-1-dengjie03%40kylinos.cn
patch subject: [PATCH v2] media: usb: uvc: Fix NULL pointer dereference during USB device hot-unplug
config: x86_64-randconfig-r071-20251128 (https://download.01.org/0day-ci/archive/20251129/202511290057.kQLrar4L-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202511290057.kQLrar4L-lkp@intel.com/
smatch warnings:
drivers/media/usb/uvc/uvc_video.c:2357 uvc_video_stop_streaming() error: we previously assumed 'stream' could be null (see line 2323)
vim +/stream +2357 drivers/media/usb/uvc/uvc_video.c
571e70dbd421056 Kieran Bingham 2018-11-05 2318 void uvc_video_stop_streaming(struct uvc_streaming *stream)
571e70dbd421056 Kieran Bingham 2018-11-05 2319 {
18ffa9a4cf426a8 Jie Deng 2025-11-22 2320 struct usb_host_config *config;
18ffa9a4cf426a8 Jie Deng 2025-11-22 2321 int i;
18ffa9a4cf426a8 Jie Deng 2025-11-22 2322
18ffa9a4cf426a8 Jie Deng 2025-11-22 @2323 if (!stream || !stream->dev || !stream->dev->udev || !stream->intf)
I don't think "stream" can be NULL,
18ffa9a4cf426a8 Jie Deng 2025-11-22 2324 goto cleanup_clock;
18ffa9a4cf426a8 Jie Deng 2025-11-22 2325
fb58e16bb783833 Kieran Bingham 2018-11-05 2326 uvc_video_stop_transfer(stream, 1);
571e70dbd421056 Kieran Bingham 2018-11-05 2327
18ffa9a4cf426a8 Jie Deng 2025-11-22 2328 config = stream->dev->udev->actconfig;
18ffa9a4cf426a8 Jie Deng 2025-11-22 2329 if (stream->intf->num_altsetting > 1 && config) {
18ffa9a4cf426a8 Jie Deng 2025-11-22 2330 /* Security Check: Check if the interface exists and is valid */
18ffa9a4cf426a8 Jie Deng 2025-11-22 2331 for (i = 0; i < config->desc.bNumInterfaces; i++) {
18ffa9a4cf426a8 Jie Deng 2025-11-22 2332 if (config->interface[i] &&
18ffa9a4cf426a8 Jie Deng 2025-11-22 2333 config->interface[i]->altsetting[0]
18ffa9a4cf426a8 Jie Deng 2025-11-22 2334 .desc.bInterfaceNumber == stream->intfnum) {
571e70dbd421056 Kieran Bingham 2018-11-05 2335 usb_set_interface(stream->dev->udev, stream->intfnum, 0);
18ffa9a4cf426a8 Jie Deng 2025-11-22 2336 break;
18ffa9a4cf426a8 Jie Deng 2025-11-22 2337 }
18ffa9a4cf426a8 Jie Deng 2025-11-22 2338 }
571e70dbd421056 Kieran Bingham 2018-11-05 2339 } else {
699b9a86a3f03ad Laurent Pinchart 2022-06-08 2340 /*
699b9a86a3f03ad Laurent Pinchart 2022-06-08 2341 * UVC doesn't specify how to inform a bulk-based device
571e70dbd421056 Kieran Bingham 2018-11-05 2342 * when the video stream is stopped. Windows sends a
571e70dbd421056 Kieran Bingham 2018-11-05 2343 * CLEAR_FEATURE(HALT) request to the video streaming
571e70dbd421056 Kieran Bingham 2018-11-05 2344 * bulk endpoint, mimic the same behaviour.
571e70dbd421056 Kieran Bingham 2018-11-05 2345 */
571e70dbd421056 Kieran Bingham 2018-11-05 2346 unsigned int epnum = stream->header.bEndpointAddress
571e70dbd421056 Kieran Bingham 2018-11-05 2347 & USB_ENDPOINT_NUMBER_MASK;
571e70dbd421056 Kieran Bingham 2018-11-05 2348 unsigned int dir = stream->header.bEndpointAddress
571e70dbd421056 Kieran Bingham 2018-11-05 2349 & USB_ENDPOINT_DIR_MASK;
571e70dbd421056 Kieran Bingham 2018-11-05 2350 unsigned int pipe;
571e70dbd421056 Kieran Bingham 2018-11-05 2351
571e70dbd421056 Kieran Bingham 2018-11-05 2352 pipe = usb_sndbulkpipe(stream->dev->udev, epnum) | dir;
571e70dbd421056 Kieran Bingham 2018-11-05 2353 usb_clear_halt(stream->dev->udev, pipe);
571e70dbd421056 Kieran Bingham 2018-11-05 2354 }
571e70dbd421056 Kieran Bingham 2018-11-05 2355
18ffa9a4cf426a8 Jie Deng 2025-11-22 2356 cleanup_clock:
141270bd95d48ea Ricardo Ribalda 2024-03-23 @2357 uvc_video_clock_cleanup(&stream->clock);
^^^^^^^^^^^^^^
But if it is then we are toasted.
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Jie On Sat, 22 Nov 2025 at 08:26, Jie Deng <dengjie03@kylinos.cn> wrote: > > Add safety checks to prevent kernel panic during the race window in > USB device disconnection. Can you share the kernel version that you are using? This patch https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c93d73c9c2cfa7658f7100d201a47c4856746222 Should prevent the race that you are describing. In your trace you have a reference to uvc_queue_streamoff that was deleted by that patch Regards! > > The issue occurs in a specific timing window during hot-unplug: > - usb_disconnect() calls usb_disable_device() which sets > dev->actconfig->interface[i] to NULL > - But dev->actconfig is not yet set to NULL > - During this window, uvc_video_stop_streaming() calls usb_set_interface() > - This eventually calls usb_ifnum_to_if() which accesses the already > NULL interface[i]->altsetting, causing a kernel panic > logs: > [ 9518.891254] Call trace: > [ 9518.894817] usb_ifnum_to_if+0x34/0x50 > [ 9518.899681] usb_set_interface+0x108/0x3c8 > [ 9518.904898] uvc_video_stop_streaming+0x3c/0x90 [uvcvideo] > [ 9518.911500] uvc_stop_streaming+0x24/0x90 [uvcvideo] > [ 9518.917583] __vb2_queue_cancel+0x44/0x458 [videobuf2_common] > [ 9518.924444] vb2_core_streamoff+0x20/0xb8 [videobuf2_common] > [ 9518.931221] vb2_streamoff+0x18/0x60 [videobuf2_v4l2] > [ 9518.937390] uvc_queue_streamoff+0x30/0x50 [uvcvideo] ^^^^^^^^ > [ 9518.943557] uvc_ioctl_streamoff+0x40/0x68 [uvcvideo] > [ 9518.949724] v4l_streamoff+0x20/0x28 > [ 9518.954415] __video_do_ioctl+0x17c/0x3e0 > [ 9518.959540] video_usercopy+0x1d8/0x558 > [ 9518.964490] video_ioctl2+0x14/0x1c > [ 9518.969094] v4l2_ioctl+0x3c/0x58 > [ 9518.973526] do_vfs_ioctl+0x374/0x7b0 > [ 9518.978304] ksys_ioctl+0x78/0xa8 > [ 9518.982734] sys_ioctl+0xc/0x18 > [ 9518.986991] __sys_trace_return+0x0/0x4 > [ 9518.991943] Code: eb04005f 54000100 f9400040 91002042 (f9400003) > [ 9518.999153] ---[ end trace f7c7d3236806d9a4 ]---
Hi Ricardo Thank you for your reply 在 2025/11/22 16:17, Ricardo Ribalda 写道: > Hi Jie > > On Sat, 22 Nov 2025 at 08:26, Jie Deng <dengjie03@kylinos.cn> wrote: >> Add safety checks to prevent kernel panic during the race window in >> USB device disconnection. > Can you share the kernel version that you are using? The kernel version I'm using is 5.4.18 > > This patch > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c93d73c9c2cfa7658f7100d201a47c4856746222 > Should prevent the race that you are describing. > > > In your trace you have a reference to uvc_queue_streamoff that was > deleted by that patch This patch may indeed eliminate the problem I described. The 5.4 longterm version should not have synchronized this patch? Thanks, Jie Deng
Hi Jie On Mon, 24 Nov 2025 at 04:08, Jie Deng <dengjie03@kylinos.cn> wrote: > > Hi Ricardo > > Thank you for your reply > > 在 2025/11/22 16:17, Ricardo Ribalda 写道: > > Hi Jie > > > > On Sat, 22 Nov 2025 at 08:26, Jie Deng <dengjie03@kylinos.cn> wrote: > >> Add safety checks to prevent kernel panic during the race window in > >> USB device disconnection. > > Can you share the kernel version that you are using? > The kernel version I'm using is 5.4.18 > > > > This patch > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c93d73c9c2cfa7658f7100d201a47c4856746222 > > Should prevent the race that you are describing. > > > > > > In your trace you have a reference to uvc_queue_streamoff that was > > deleted by that patch > > This patch may indeed eliminate the problem I described. > > The 5.4 longterm version should not have synchronized this patch? Seems that the patch that fixed the issue: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/media/usb/uvc/uvc_driver.c?id=c9ec6f1736363b2b2bb4e266997389740f628441 Was only backported until 5.10 5.4 is EOL this December. So it is probably not worth doing anything more. Regards! > > > Thanks, > > Jie Deng > -- Ricardo Ribalda
Hi Ricardo Thank you for your reply 在 2025/11/24 17:06, Ricardo Ribalda 写道: > Hi Jie > > > > On Mon, 24 Nov 2025 at 04:08, Jie Deng <dengjie03@kylinos.cn> wrote: >> Hi Ricardo >> >> Thank you for your reply >> >> 在 2025/11/22 16:17, Ricardo Ribalda 写道: >>> Hi Jie >>> >>> On Sat, 22 Nov 2025 at 08:26, Jie Deng <dengjie03@kylinos.cn> wrote: >>>> Add safety checks to prevent kernel panic during the race window in >>>> USB device disconnection. >>> Can you share the kernel version that you are using? >> The kernel version I'm using is 5.4.18 >>> This patch >>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c93d73c9c2cfa7658f7100d201a47c4856746222 >>> Should prevent the race that you are describing. >>> >>> >>> In your trace you have a reference to uvc_queue_streamoff that was >>> deleted by that patch >> This patch may indeed eliminate the problem I described. >> >> The 5.4 longterm version should not have synchronized this patch? > Seems that the patch that fixed the issue: > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/media/usb/uvc/uvc_driver.c?id=c9ec6f1736363b2b2bb4e266997389740f628441 1. What this patch does: Problem scenario: When a USB device is disconnected, the kernel initiates the unregistration process, but the device might still be in a streaming state. 2. The issue fixed by my patch submission: 1)Problem scenario: When userspace actively stops streaming, the USB device gets disconnected during the stopping process. 2)Fix method: In the stream stopping function, check whether the USB device is still connected to avoid accessing structures of already disconnected devices. This is fixed by adding null pointer checks. The patch I submitted addresses a different race condition. Thanks, Jie Deng > > Was only backported until 5.10 > > 5.4 is EOL this December. So it is probably not worth doing anything more. > > Regards! > >> >> Thanks, >> >> Jie Deng >> >
Hi Jie On Tue, 25 Nov 2025 at 04:14, Jie Deng <dengjie03@kylinos.cn> wrote: > > Hi Ricardo > > Thank you for your reply > > 在 2025/11/24 17:06, Ricardo Ribalda 写道: > > Hi Jie > > > > > > > > On Mon, 24 Nov 2025 at 04:08, Jie Deng <dengjie03@kylinos.cn> wrote: > >> Hi Ricardo > >> > >> Thank you for your reply > >> > >> 在 2025/11/22 16:17, Ricardo Ribalda 写道: > >>> Hi Jie > >>> > >>> On Sat, 22 Nov 2025 at 08:26, Jie Deng <dengjie03@kylinos.cn> wrote: > >>>> Add safety checks to prevent kernel panic during the race window in > >>>> USB device disconnection. > >>> Can you share the kernel version that you are using? > >> The kernel version I'm using is 5.4.18 > >>> This patch > >>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c93d73c9c2cfa7658f7100d201a47c4856746222 > >>> Should prevent the race that you are describing. > >>> > >>> > >>> In your trace you have a reference to uvc_queue_streamoff that was > >>> deleted by that patch > >> This patch may indeed eliminate the problem I described. > >> > >> The 5.4 longterm version should not have synchronized this patch? > > Seems that the patch that fixed the issue: > > > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/media/usb/uvc/uvc_driver.c?id=c9ec6f1736363b2b2bb4e266997389740f628441 > 1. What this patch does: > > Problem scenario: When a USB device is disconnected, the kernel > initiates the > > unregistration process, but the device might still be in a streaming state. > > > 2. The issue fixed by my patch submission: > 1)Problem scenario: When userspace actively stops streaming, the USB > device gets > > disconnected during the stopping process. > > 2)Fix method: In the stream stopping function, check whether the USB > device is still > > connected to avoid accessing structures of already disconnected devices. > This is fixed > > by adding null pointer checks. Your patch only reduces the window for the race condition, but does not solve it. If the device is disconnected between the NULL check and the structure use, there will still be a kernel panic. The proper way to fix it is with: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c93d73c9c2cfa7658f7100d201a47c4856746222 or https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c9ec6f1736363b2b2bb4e266997389740f628441 Those patches were not backported to 5.4, only to 5.10. 5.4 will be EOL in 5 days Please move your product to a newer kernel (ideally the latest released by Linus) Regards! > > The patch I submitted addresses a different race condition. > > > Thanks, > > Jie Deng > > > > > Was only backported until 5.10 > > > > 5.4 is EOL this December. So it is probably not worth doing anything more. > > > > Regards! > > > >> > >> Thanks, > >> > >> Jie Deng > >> > > -- Ricardo Ribalda
在 2025/11/25 16:29, Ricardo Ribalda 写道: > Hi Jie > > > On Tue, 25 Nov 2025 at 04:14, Jie Deng <dengjie03@kylinos.cn> wrote: >> Hi Ricardo >> >> Thank you for your reply >> >> 在 2025/11/24 17:06, Ricardo Ribalda 写道: >>> Hi Jie >>> >>> >>> >>> On Mon, 24 Nov 2025 at 04:08, Jie Deng <dengjie03@kylinos.cn> wrote: >>>> Hi Ricardo >>>> >>>> Thank you for your reply >>>> >>>> 在 2025/11/22 16:17, Ricardo Ribalda 写道: >>>>> Hi Jie >>>>> >>>>> On Sat, 22 Nov 2025 at 08:26, Jie Deng <dengjie03@kylinos.cn> wrote: >>>>>> Add safety checks to prevent kernel panic during the race window in >>>>>> USB device disconnection. >>>>> Can you share the kernel version that you are using? >>>> The kernel version I'm using is 5.4.18 >>>>> This patch >>>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c93d73c9c2cfa7658f7100d201a47c4856746222 >>>>> Should prevent the race that you are describing. >>>>> >>>>> >>>>> In your trace you have a reference to uvc_queue_streamoff that was >>>>> deleted by that patch >>>> This patch may indeed eliminate the problem I described. >>>> >>>> The 5.4 longterm version should not have synchronized this patch? >>> Seems that the patch that fixed the issue: >>> >>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/media/usb/uvc/uvc_driver.c?id=c9ec6f1736363b2b2bb4e266997389740f628441 >> 1. What this patch does: >> >> Problem scenario: When a USB device is disconnected, the kernel >> initiates the >> >> unregistration process, but the device might still be in a streaming state. >> >> >> 2. The issue fixed by my patch submission: >> 1)Problem scenario: When userspace actively stops streaming, the USB >> device gets >> >> disconnected during the stopping process. >> >> 2)Fix method: In the stream stopping function, check whether the USB >> device is still >> >> connected to avoid accessing structures of already disconnected devices. >> This is fixed >> >> by adding null pointer checks. > Your patch only reduces the window for the race condition, but does > not solve it. > > If the device is disconnected between the NULL check and the structure > use, there will still be a kernel panic. > > The proper way to fix it is with: > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c93d73c9c2cfa7658f7100d201a47c4856746222 > or > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c9ec6f1736363b2b2bb4e266997389740f628441 > > Those patches were not backported to 5.4, only to 5.10. 5.4 will be > EOL in 5 days > > Please move your product to a newer kernel (ideally the latest > released by Linus) > > Regards! > >> The patch I submitted addresses a different race condition. >> >> >> Thanks, >> >> Jie Deng >> >>> Was only backported until 5.10 >>> >>> 5.4 is EOL this December. So it is probably not worth doing anything more. >>> >>> Regards! Ok. Thank you for your guidance. Jie Deng >>> >>>> Thanks, >>>> >>>> Jie Deng >>>> > >
© 2016 - 2025 Red Hat, Inc.