commit 3dd075fe8ebbc6fcbf998f81a75b8c4b159a6195 upstream.
Per UVC 1.1+ specification 3.7.2, units and terminals must have a non-zero
unique ID.
```
Each Unit and Terminal within the video function is assigned a unique
identification number, the Unit ID (UID) or Terminal ID (TID), contained in
the bUnitID or bTerminalID field of the descriptor. The value 0x00 is
reserved for undefined ID,
```
So, deny allocating an entity with ID 0 or an ID that belongs to a unit
that is already added to the list of entities.
This also prevents some syzkaller reproducers from triggering warnings due
to a chain of entities referring to themselves. In one particular case, an
Output Unit is connected to an Input Unit, both with the same ID of 1. But
when looking up for the source ID of the Output Unit, that same entity is
found instead of the input entity, which leads to such warnings.
In another case, a backward chain was considered finished as the source ID
was 0. Later on, that entity was found, but its pads were not valid.
Here is a sample stack trace for one of those cases.
[ 20.650953] usb 1-1: new high-speed USB device number 2 using dummy_hcd
[ 20.830206] usb 1-1: Using ep0 maxpacket: 8
[ 20.833501] usb 1-1: config 0 descriptor??
[ 21.038518] usb 1-1: string descriptor 0 read error: -71
[ 21.038893] usb 1-1: Found UVC 0.00 device <unnamed> (2833:0201)
[ 21.039299] uvcvideo 1-1:0.0: Entity type for entity Output 1 was not initialized!
[ 21.041583] uvcvideo 1-1:0.0: Entity type for entity Input 1 was not initialized!
[ 21.042218] ------------[ cut here ]------------
[ 21.042536] WARNING: CPU: 0 PID: 9 at drivers/media/mc/mc-entity.c:1147 media_create_pad_link+0x2c4/0x2e0
[ 21.043195] Modules linked in:
[ 21.043535] CPU: 0 UID: 0 PID: 9 Comm: kworker/0:1 Not tainted 6.11.0-rc7-00030-g3480e43aeccf #444
[ 21.044101] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014
[ 21.044639] Workqueue: usb_hub_wq hub_event
[ 21.045100] RIP: 0010:media_create_pad_link+0x2c4/0x2e0
[ 21.045508] Code: fe e8 20 01 00 00 b8 f4 ff ff ff 48 83 c4 30 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc 0f 0b eb e9 0f 0b eb 0a 0f 0b eb 06 <0f> 0b eb 02 0f 0b b8 ea ff ff ff eb d4 66 2e 0f 1f 84 00 00 00 00
[ 21.046801] RSP: 0018:ffffc9000004b318 EFLAGS: 00010246
[ 21.047227] RAX: ffff888004e5d458 RBX: 0000000000000000 RCX: ffffffff818fccf1
[ 21.047719] RDX: 000000000000007b RSI: 0000000000000000 RDI: ffff888004313290
[ 21.048241] RBP: ffff888004313290 R08: 0001ffffffffffff R09: 0000000000000000
[ 21.048701] R10: 0000000000000013 R11: 0001888004313290 R12: 0000000000000003
[ 21.049138] R13: ffff888004313080 R14: ffff888004313080 R15: 0000000000000000
[ 21.049648] FS: 0000000000000000(0000) GS:ffff88803ec00000(0000) knlGS:0000000000000000
[ 21.050271] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 21.050688] CR2: 0000592cc27635b0 CR3: 000000000431c000 CR4: 0000000000750ef0
[ 21.051136] PKRU: 55555554
[ 21.051331] Call Trace:
[ 21.051480] <TASK>
[ 21.051611] ? __warn+0xc4/0x210
[ 21.051861] ? media_create_pad_link+0x2c4/0x2e0
[ 21.052252] ? report_bug+0x11b/0x1a0
[ 21.052540] ? trace_hardirqs_on+0x31/0x40
[ 21.052901] ? handle_bug+0x3d/0x70
[ 21.053197] ? exc_invalid_op+0x1a/0x50
[ 21.053511] ? asm_exc_invalid_op+0x1a/0x20
[ 21.053924] ? media_create_pad_link+0x91/0x2e0
[ 21.054364] ? media_create_pad_link+0x2c4/0x2e0
[ 21.054834] ? media_create_pad_link+0x91/0x2e0
[ 21.055131] ? _raw_spin_unlock+0x1e/0x40
[ 21.055441] ? __v4l2_device_register_subdev+0x202/0x210
[ 21.055837] uvc_mc_register_entities+0x358/0x400
[ 21.056144] uvc_register_chains+0x1fd/0x290
[ 21.056413] uvc_probe+0x380e/0x3dc0
[ 21.056676] ? __lock_acquire+0x5aa/0x26e0
[ 21.056946] ? find_held_lock+0x33/0xa0
[ 21.057196] ? kernfs_activate+0x70/0x80
[ 21.057533] ? usb_match_dynamic_id+0x1b/0x70
[ 21.057811] ? find_held_lock+0x33/0xa0
[ 21.058047] ? usb_match_dynamic_id+0x55/0x70
[ 21.058330] ? lock_release+0x124/0x260
[ 21.058657] ? usb_match_one_id_intf+0xa2/0x100
[ 21.058997] usb_probe_interface+0x1ba/0x330
[ 21.059399] really_probe+0x1ba/0x4c0
[ 21.059662] __driver_probe_device+0xb2/0x180
[ 21.059944] driver_probe_device+0x5a/0x100
[ 21.060170] __device_attach_driver+0xe9/0x160
[ 21.060427] ? __pfx___device_attach_driver+0x10/0x10
[ 21.060872] bus_for_each_drv+0xa9/0x100
[ 21.061312] __device_attach+0xed/0x190
[ 21.061812] device_initial_probe+0xe/0x20
[ 21.062229] bus_probe_device+0x4d/0xd0
[ 21.062590] device_add+0x308/0x590
[ 21.062912] usb_set_configuration+0x7b6/0xaf0
[ 21.063403] usb_generic_driver_probe+0x36/0x80
[ 21.063714] usb_probe_device+0x7b/0x130
[ 21.063936] really_probe+0x1ba/0x4c0
[ 21.064111] __driver_probe_device+0xb2/0x180
[ 21.064577] driver_probe_device+0x5a/0x100
[ 21.065019] __device_attach_driver+0xe9/0x160
[ 21.065403] ? __pfx___device_attach_driver+0x10/0x10
[ 21.065820] bus_for_each_drv+0xa9/0x100
[ 21.066094] __device_attach+0xed/0x190
[ 21.066535] device_initial_probe+0xe/0x20
[ 21.066992] bus_probe_device+0x4d/0xd0
[ 21.067250] device_add+0x308/0x590
[ 21.067501] usb_new_device+0x347/0x610
[ 21.067817] hub_event+0x156b/0x1e30
[ 21.068060] ? process_scheduled_works+0x48b/0xaf0
[ 21.068337] process_scheduled_works+0x5a3/0xaf0
[ 21.068668] worker_thread+0x3cf/0x560
[ 21.068932] ? kthread+0x109/0x1b0
[ 21.069133] kthread+0x197/0x1b0
[ 21.069343] ? __pfx_worker_thread+0x10/0x10
[ 21.069598] ? __pfx_kthread+0x10/0x10
[ 21.069908] ret_from_fork+0x32/0x40
[ 21.070169] ? __pfx_kthread+0x10/0x10
[ 21.070424] ret_from_fork_asm+0x1a/0x30
[ 21.070737] </TASK>
Cc: stable@vger.kernel.org
Reported-by: syzbot+0584f746fde3d52b4675@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=0584f746fde3d52b4675
Reported-by: syzbot+dd320d114deb3f5bb79b@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=dd320d114deb3f5bb79b
Fixes: a3fbc2e6bb05 ("media: mc-entity.c: use WARN_ON, validate link pads")
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://lore.kernel.org/r/20240913180601.1400596-2-cascardo@igalia.com
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
[ ribalda: The context around the changes differs from master. This
version is also missing the gpio unit, so that part is gone from the
patch. ]
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
commit c9ec6f1736363b2b2bb4e266997389740f628441 upstream.
uvc_unregister_video() can be called asynchronously from
uvc_disconnect(). If the device is still streaming when that happens, a
plethora of race conditions can occur.
Make sure that the device has stopped streaming before exiting this
function.
If the user still holds handles to the driver's file descriptors, any
ioctl will return -ENODEV from the v4l2 core.
This change makes uvc more consistent with the rest of the v4l2 drivers
using the vb2_fop_* and vb2_ioctl_* helpers.
This driver (and many other usb drivers) always had this problem, but it
wasn't possible to easily fix this until the vb2_video_unregister_device()
helper was added. So the Fixes tag points to the creation of that helper.
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Suggested-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Fixes: f729ef5796d8 ("media: videobuf2-v4l2.c: add vb2_video_unregister_device helper function")
Cc: stable@vger.kernel.org # 5.10.x
[hverkuil: add note regarding Fixes version]
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
commit ecf2b43018da9579842c774b7f35dbe11b5c38dd upstream.
This can lead to out of bounds writes since frames of this type were not
taken into account when calculating the size of the frames buffer in
uvc_parse_streaming.
Fixes: c0efd232929c ("V4L/DVB (8145a): USB Video Class driver")
Signed-off-by: Benoit Sevens <bsevens@google.com>
Cc: stable@vger.kernel.org
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ Upstream commit c8931ef55bd325052ec496f242aea7f6de47dc9c ]
Struct uvc_frame and interval (u32*) are packaged together on
streaming->formats on a single contiguous allocation.
Right now they are allocated right after uvc_format, without taking into
consideration their required alignment.
This is working fine because both structures have a field with a
pointer, but it will stop working when the sizeof() of any of those
structs is not a multiple of the sizeof(void*).
Enforce that alignment during the allocation.
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://lore.kernel.org/r/20240404-uvc-align-v2-1-9e104b0ecfbd@chromium.org
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
commit 5f36851c36b30f713f588ed2b60aa7b4512e2c76 upstream.
Entity controls should get_cur using an entity-defined function
instead of via a query. Fix this in uvc_ctrl_set.
Fixes: 65900c581d01 ("media: uvcvideo: Allow entity-defined get_info and get_cur")
Signed-off-by: Yunke Cao <yunkec@google.com>
Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ Upstream commit 9e3d55fbd160b3ca376599a68b4cddfdc67d4153 ]
The bandwidth fixup quirk doesn't know that SuperSpeed exists and has
the same 8 service intervals per millisecond as High Speed, hence its
calculations are wrong.
Assume that all speeds from HS up use 8 intervals per millisecond.
No further changes are needed, updated code has been confirmed to work
with all speeds from FS to SS.
Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://lore.kernel.org/r/20240414190040.2255a0bc@foxbook
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 5cd7c25f6f0576073b3d03bc4cfb1e8ca63a1195 ]
Some SunplusIT cameras took a borderline interpretation of the UVC 1.5
standard, and fill the PTS and SCR fields with invalid data if the
package does not contain data.
"STC must be captured when the first video data of a video frame is put
on the USB bus."
Some SunplusIT devices send, e.g.,
buffer: 0xa7755c00 len 000012 header:0x8c stc 00000000 sof 0000 pts 00000000
buffer: 0xa7755c00 len 000012 header:0x8c stc 00000000 sof 0000 pts 00000000
buffer: 0xa7755c00 len 000668 header:0x8c stc 73779dba sof 070c pts 7376d37a
While the UVC specification meant that the first two packets shouldn't
have had the SCR bit set in the header.
This borderline/buggy interpretation has been implemented in a variety
of devices, from directly SunplusIT and from other OEMs that rebrand
SunplusIT products. So quirking based on VID:PID will be problematic.
All the affected modules have the following extension unit:
VideoControl Interface Descriptor:
guidExtensionCode {82066163-7050-ab49-b8cc-b3855e8d221d}
But the vendor plans to use that GUID in the future and fix the bug,
this means that we should use heuristic to figure out the broken
packets.
This patch takes care of this.
lsusb of one of the affected cameras:
Bus 001 Device 003: ID 1bcf:2a01 Sunplus Innovation Technology Inc.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.01
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 ?
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x1bcf Sunplus Innovation Technology Inc.
idProduct 0x2a01
bcdDevice 0.02
iManufacturer 1 SunplusIT Inc
iProduct 2 HanChen Wise Camera
iSerial 3 01.00.00
bNumConfigurations 1
Tested-by: HungNien Chen <hn.chen@sunplusit.com>
Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Link: https://lore.kernel.org/r/20240323-resend-hwtimestamp-v10-2-b08e590d97c7@chromium.org
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 86419686e66da5b90a07fb8a40ab138fe97189b5 ]
When the UVC device has a control that is readonly it doesn't set the
SET_CUR flag. For example the privacy control has SET_CUR flag set in
the defaults in the `uvc_ctrls` variable. Even if the device does not
have it set, it's not cleared by uvc_ctrl_get_flags().
Originally written with assignment in commit 859086ae3636 ("media:
uvcvideo: Apply flags from device to actual properties"). But changed to
|= in commit 0dc68cabdb62 ("media: uvcvideo: Prevent setting unavailable
flags"). It would not clear the default flags.
With this patch applied the correct flags are reported to user space.
Tested with:
```
> v4l2-ctl --list-ctrls | grep privacy
privacy 0x009a0910 (bool) : default=0 value=0 flags=read-only
```
Signed-off-by: Daniel Schaefer <dhs@frame.work>
Fixes: 0dc68cabdb62 ("media: uvcvideo: Prevent setting unavailable flags")
Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://lore.kernel.org/r/20240602065053.36850-1-dhs@frame.work
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 65900c581d014499f0f8ceabfc02c652e9a88771 ]
Allows controls to get their properties and current value
from an entity-defined function instead of via a query to the USB
device.
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Stable-dep-of: 86419686e66d ("media: uvcvideo: Override default flags")
Signed-off-by: Sasha Levin <sashal@kernel.org>