diff options
| author | Nguyen Quang Le Kien <khiemtranzo532001@gmail.com> | 2026-08-03 18:40:08 +0800 |
|---|---|---|
| committer | Hans Verkuil <hverkuil+cisco@kernel.org> | 2026-09-08 15:10:03 +0200 |
| commit | 8a3435f98175aa611e6cb347738f85d7cd6df792 (patch) | |
| tree | 672696026f79cc98e4094832380fe38054c077b3 | |
| parent | 6e30287eaf3e41b86dfb86df3b811526693d74b4 (diff) | |
| download | linux-next-8a3435f98175aa611e6cb347738f85d7cd6df792.tar.gz linux-next-8a3435f98175aa611e6cb347738f85d7cd6df792.zip | |
media: pvrusb2: fix URB pending flag leak on invalid endpoint
In pvr2_send_request_ex(), when usb_urb_ep_type_check() fails for either
the write or read control endpoint, the code returned -EINVAL directly
without clearing the corresponding pending flags (ctl_write_pend_flag or
ctl_read_pend_flag) or going through the done: cleanup path.
This left the pending flags set while the URBs were never actually
submitted. On the next call to pvr2_send_request_ex(), the URBs would be
filled and submitted while the kernel still considered them active,
triggering the WARNING "URB submitted while active" in usb_submit_urb().
Fix this by:
- Clearing the pending flag before returning on invalid endpoint
- Using goto done instead of direct return to go through proper cleanup
- For the read endpoint case, unlinking the write URB if it was already
submitted and waiting for its completion before returning
Reported-by: syzbot+20fef510634faf733060@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=20fef510634faf733060
Signed-off-by: Nguyen Quang Le Kien <khiemtranzo532001@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
| -rw-r--r-- | drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index 3c270ef00752..3a857e95bc0c 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -3669,7 +3669,9 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, pvr2_trace( PVR2_TRACE_ERROR_LEGS, "Invalid write control endpoint"); - return -EINVAL; + hdw->ctl_write_pend_flag = 0; + status = -EINVAL; + goto done; } status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL); if (status < 0) { @@ -3699,7 +3701,13 @@ status); pvr2_trace( PVR2_TRACE_ERROR_LEGS, "Invalid read control endpoint"); - return -EINVAL; + hdw->ctl_read_pend_flag = 0; + status = -EINVAL; + if (hdw->ctl_write_pend_flag) { + usb_unlink_urb(hdw->ctl_write_urb); + wait_for_completion(&hdw->ctl_done); + } + goto done; } status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL); if (status < 0) { |
