FAILED: patch "[PATCH] media: usbtv: fix null-pointer dereference on disconnect" failed to apply to 6.12-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x cb705f75d03e946a4514488beb9e3bac9bcdb2e6
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026110227-ravine-cider-7c49@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From cb705f75d03e946a4514488beb9e3bac9bcdb2e6 Mon Sep 17 00:00:00 2001
From: Aleksandr Nogikh <[email protected]>
Date: Mon, 17 Aug 2026 14:09:49 +0000
Subject: [PATCH] media: usbtv: fix null-pointer dereference on disconnect
A null-pointer dereference can occur in usb_make_path() when called from usbtv_querycap() (and other ioctl handlers) during device disconnection.
Oops: general protection fault, probably for non-canonical address 0xdffffc000000000a: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000050-0x0000000000000057] RIP: 0010:usb_make_path include/linux/usb.h:985 [inline] RIP: 0010:usbtv_querycap+0x9c/0x100 drivers/media/usb/usbtv/usbtv-video.c:612 ... Call Trace: <TASK> v4l_querycap+0x236/0x470 drivers/media/v4l2-core/v4l2-ioctl.c:1106 __video_do_ioctl+0x8af/0xc70 drivers/media/v4l2-core/v4l2-ioctl.c:3133 video_usercopy+0x860/0x1430 drivers/media/v4l2-core/v4l2-ioctl.c:3475 v4l2_ioctl+0x18d/0x1e0 drivers/media/v4l2-core/v4l2-dev.c:366 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0x174/0x580 arch/x86/entry/syscall_64.c:94
This happens due to a race condition between the USB device disconnect routine (usbtv_disconnect()) and V4L2 ioctls. When the device is disconnected, usbtv_disconnect() sets usbtv->udev = NULL without holding the usbtv->v4l2_lock mutex. Concurrently, an ioctl handler like usbtv_querycap() can be executing under the v4l2_lock and attempt to use usbtv->udev, leading to a crash.
To fix this, move the usbtv->udev = NULL assignment into usbtv_video_free() and protect it with mutex_lock(&usbtv->v4l2_lock). This ensures that no non-queue ioctl handler can run concurrently with the pointer being nullified. If an ioctl is already running, the mutex will block the disconnect path until the ioctl finishes. If an ioctl is blocked waiting for the lock, it will acquire it after the disconnect routine releases it, but will then check video_is_registered() (which was cleared by vb2_video_unregister_device()) and safely return -ENODEV.
Acquiring v4l2_lock after vb2_video_unregister_device() avoids reintroducing a historical deadlock issue, and usbtv_audio_free() remains safe as it is called before usbtv_video_free().
drivers/media/usb/usbtv/usbtv-core.c +0 -2
@@ -139,8 +139,6 @@ static void usbtv_disconnect(struct usb_interface *intf)usbtv_audio_free (usbtv);usbtv_video_free (usbtv); - usbtv->udev =NULL ; -/* the usbtv structure will be deallocated when v4l2 will be done using it */ v4l2_device_put (&usbtv->v4l2_dev);
drivers/media/usb/usbtv/usbtv-video.c +4 -0
@@ -966,5 +966,9 @@ void usbtv_video_free(struct usbtv *usbtv)vb2_video_unregister_device (&usbtv->vdev);v4l2_device_disconnect (&usbtv->v4l2_dev); +mutex_lock (&usbtv->v4l2_lock); + usbtv->udev =NULL ; +mutex_unlock (&usbtv->v4l2_lock); +v4l2_device_put (&usbtv->v4l2_dev); }
Sasha Levin
maintainerPATCH 1/2 media: usbtv: drop redundant device reference
From: Johan Hovold <[email protected]>
[ Upstream commit dbc6798b80481a20f9aff671bc4d529eae63c9e8 ]
Driver core holds a reference to the USB interface and its parent USB device while the interface is bound to a driver and there is no need to take additional references unless the structures are needed after disconnect.
Drop the redundant device reference to reduce cargo culting, make it easier to spot drivers where an extra reference is needed, and reduce the risk of memory leaks when drivers fail to release it.
Stable-dep-of: cb705f75d03e ("media: usbtv: fix null-pointer dereference on disconnect")
--- drivers/media/usb/usbtv/usbtv-core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/media/usb/usbtv/usbtv-core.c +1 -3
@@ -91,7 +91,7 @@ static int usbtv_probe(struct usb_interface *intf,if (usbtv ==NULL )return -ENOMEM ; usbtv->dev = dev; - usbtv->udev =usb_get_dev (interface_to_usbdev (intf)); + usbtv->udev =interface_to_usbdev (intf); usbtv->iso_size = size;
@@ -119,7 +119,6 @@ static int usbtv_probe(struct usb_interface *intf, usbtv_video_fail:usb_set_intfdata (intf,NULL ); -usb_put_dev (usbtv->udev);kfree (usbtv);return ret;
@@ -137,7 +136,6 @@ static void usbtv_disconnect(struct usb_interface *intf)usbtv_audio_free (usbtv);usbtv_video_free (usbtv); -usb_put_dev (usbtv->udev); usbtv->udev =NULL ;/* the usbtv structure will be deallocated when v4l2 will be
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 media: usbtv: fix null-pointer dereference on disconnect
From: Aleksandr Nogikh <[email protected]>
[ Upstream commit cb705f75d03e946a4514488beb9e3bac9bcdb2e6 ]
A null-pointer dereference can occur in usb_make_path() when called from usbtv_querycap() (and other ioctl handlers) during device disconnection.
Oops: general protection fault, probably for non-canonical address 0xdffffc000000000a: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000050-0x0000000000000057] RIP: 0010:usb_make_path include/linux/usb.h:985 [inline] RIP: 0010:usbtv_querycap+0x9c/0x100 drivers/media/usb/usbtv/usbtv-video.c:612 ... Call Trace: <TASK> v4l_querycap+0x236/0x470 drivers/media/v4l2-core/v4l2-ioctl.c:1106 __video_do_ioctl+0x8af/0xc70 drivers/media/v4l2-core/v4l2-ioctl.c:3133 video_usercopy+0x860/0x1430 drivers/media/v4l2-core/v4l2-ioctl.c:3475 v4l2_ioctl+0x18d/0x1e0 drivers/media/v4l2-core/v4l2-dev.c:366 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0x174/0x580 arch/x86/entry/syscall_64.c:94
This happens due to a race condition between the USB device disconnect routine (usbtv_disconnect()) and V4L2 ioctls. When the device is disconnected, usbtv_disconnect() sets usbtv->udev = NULL without holding the usbtv->v4l2_lock mutex. Concurrently, an ioctl handler like usbtv_querycap() can be executing under the v4l2_lock and attempt to use usbtv->udev, leading to a crash.
To fix this, move the usbtv->udev = NULL assignment into usbtv_video_free() and protect it with mutex_lock(&usbtv->v4l2_lock). This ensures that no non-queue ioctl handler can run concurrently with the pointer being nullified. If an ioctl is already running, the mutex will block the disconnect path until the ioctl finishes. If an ioctl is blocked waiting for the lock, it will acquire it after the disconnect routine releases it, but will then check video_is_registered() (which was cleared by vb2_video_unregister_device()) and safely return -ENODEV.
Acquiring v4l2_lock after vb2_video_unregister_device() avoids reintroducing a historical deadlock issue, and usbtv_audio_free() remains safe as it is called before usbtv_video_free().
--- drivers/media/usb/usbtv/usbtv-core.c | 2 -- drivers/media/usb/usbtv/usbtv-video.c | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/media/usb/usbtv/usbtv-core.c +0 -2
@@ -136,8 +136,6 @@ static void usbtv_disconnect(struct usb_interface *intf)usbtv_audio_free (usbtv);usbtv_video_free (usbtv); - usbtv->udev =NULL ; -/* the usbtv structure will be deallocated when v4l2 will be done using it */ v4l2_device_put (&usbtv->v4l2_dev);
drivers/media/usb/usbtv/usbtv-video.c +4 -0
@@ -970,5 +970,9 @@ void usbtv_video_free(struct usbtv *usbtv)vb2_video_unregister_device (&usbtv->vdev);v4l2_device_disconnect (&usbtv->v4l2_dev); +mutex_lock (&usbtv->v4l2_lock); + usbtv->udev =NULL ; +mutex_unlock (&usbtv->v4l2_lock); +v4l2_device_put (&usbtv->v4l2_dev); }
Signature · 1 line
2.53.0