Re: [PATCH RFC v3] usb: gadget: uvc: check endpoint enabled state in uvcg_video_enable()

Aleksandr Nogikh <[email protected]>
Newsgroups dev.linux.lists.syzbot
Message-ID <CANp29Y6GVqfrYM72u9ro6W--bPAB6Oa+pYwG0EQ8Pq4w47XTsA@mail.gmail.com>
On Wed, Aug 12, 2026 at 5:21 PM syzbot <[email protected]> wrote:
>
> A NULL pointer dereference can occur in uvc_video_prep_requests() if
> userspace issues a VIDIOC_STREAMON ioctl before the USB host has fully
> configured the streaming endpoint.
>
> When userspace calls VIDIOC_STREAMON, the driver handles it in
> uvc_v4l2_streamon(), which in turn calls uvcg_video_enable(). Currently,
> uvcg_video_enable() only checks if the endpoint pointer is allocated
> (video->ep == NULL), but it fails to check if the endpoint is actually
> enabled (video->ep->enabled).
>
> The endpoint descriptor (video->ep->desc) is only assigned when the USB
> host explicitly selects the streaming alternate setting via a SET_INTERFACE
> control request. If userspace prematurely calls VIDIOC_STREAMON before the
> host has selected the streaming alternate setting, video->ep->desc will
> still be NULL.
>
> Because uvcg_video_enable() does not verify the endpoint's enabled state,
> it proceeds to call uvc_video_alloc_requests() and then
> uvc_video_prep_requests(). Inside uvc_video_prep_requests(), the code
> unconditionally dereferences video->ep->desc, resulting in a KASAN
> null-ptr-deref / general protection fault:
>
> Oops: general protection fault, probably for non-canonical address
> 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
> KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
> RIP: 0010:usb_endpoint_xfer_isoc include/uapi/linux/usb/ch9.h:571 [inline]
> RIP: 0010:uvc_video_prep_requests
> drivers/usb/gadget/function/uvc_video.c:508 [inline]
> RIP: 0010:uvc_video_alloc_requests
> drivers/usb/gadget/function/uvc_video.c:559 [inline]
> RIP: 0010:uvcg_video_enable+0x142/0xe70
> drivers/usb/gadget/function/uvc_video.c:784
> Call Trace:
>  <TASK>
>  uvc_v4l2_streamon+0x7e/0x110 drivers/usb/gadget/function/uvc_v4l2.c:531
>  __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
>
> To fix this, update uvcg_video_enable() to also verify that the endpoint is
> enabled (!video->ep->enabled). This ensures that if userspace prematurely
> calls VIDIOC_STREAMON, the driver will safely reject the request with
> -ENODEV instead of crashing the kernel.
>
> Fixes: 48dbe731171e ("usb: gadget: uvc: set req_size and n_requests based on the frame interval")
> Assisted-by: Gemini:gemini-3.6-flash Gemini:gemini-3.1-pro-preview syzbot
> Reported-by: [email protected]
> Closes: https://syzkaller.appspot.com/bug?extid=44835f0858f11e3e923c
> Link: https://syzkaller.appspot.com/ai_job?id=4091c0e6-1fa1-4376-b736-3b983cb8ff62
> To: "Greg Kroah-Hartman" <[email protected]>
> To: <[email protected]>
> To: "Michael Grzeschik" <[email protected]>
> Cc: "Frank Li" <[email protected]>
> Cc: "Jimmy Hu" <[email protected]>
> Cc: "Hans Verkuil" <[email protected]>
> Cc: "Kees Cook" <[email protected]>
> Cc: "Laurent Pinchart" <[email protected]>
> Cc: <[email protected]>
> Cc: "Muhammad Bilal" <[email protected]>
> Cc: "Junzhong Pan" <[email protected]>
> Cc: "Xu Yang" <[email protected]>
>
> ---
> v3:
> - Removed redundant video->ep->desc checks in uvcg_video_enable() and uvc_video_alloc_requests().
> - Dropped uvc->state transition changes in uvc_v4l2_streamon().
>
> v2:
> - Check that uvc->state is UVC_STATE_CONNECTED in uvc_v4l2_streamon() before allowing streaming.
> - Update uvc->state to UVC_STATE_STREAMING before calling uvcg_video_enable(), and revert it on failure.
> - Check video->ep->desc in addition to video->ep->enabled in uvcg_video_enable().
> - Add safety checks for video->ep, video->ep->enabled, and video->ep->desc in uvc_video_alloc_requests().
> https://lore.kernel.org/all/[email protected]/T/
>
> v1:
> https://lore.kernel.org/all/[email protected]/T/
> ---
> diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c
> index dfa0521a2..17f0bcd3a 100644
> --- a/drivers/usb/gadget/function/uvc_v4l2.c
> +++ b/drivers/usb/gadget/function/uvc_v4l2.c
> @@ -527,6 +527,9 @@ uvc_v4l2_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
>         if (type != video->queue.queue.type)
>                 return -EINVAL;
>
> +       if (uvc->state != UVC_STATE_CONNECTED)
> +               return -ENODEV;
> +

Should we also check for UVC_STATE_STREAMING as well?

>         /* Enable UVC video. */
>         ret = uvcg_video_enable(video);
>         if (ret < 0)
> diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
> index 2f9700b3f..d4aeedacc 100644
> --- a/drivers/usb/gadget/function/uvc_video.c
> +++ b/drivers/usb/gadget/function/uvc_video.c
> @@ -764,7 +764,7 @@ int uvcg_video_enable(struct uvc_video *video)
>  {
>         int ret;
>
> -       if (video->ep == NULL) {
> +       if (video->ep == NULL || !video->ep->enabled) {
>                 uvcg_info(&video->uvc->func,
>                           "Video enable failed, device is uninitialized.\n");
>                 return -ENODEV;
>
>
> base-commit: db2ddb87143519e20a95aa36c60b36107b736a58
> --
> This is an AI-generated patch subject to moderation.
> Reply with '#syz upstream' to Sign-off the patch as a human author
> and send it to the upstream kernel mailing lists.
> Reply with '#syz reject' to reject it ('#syz unreject' to undo).
>
> See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
> You can comment on the patch as usual, syzbot will try to address
> the comments and send a new version of the patch if necessary.
> syzbot engineers can be reached at [email protected].
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.