<feed xmlns='http://www.w3.org/2005/Atom'>
<title>src/sys/dev/usb/video, branch main</title>
<subtitle>FreeBSD source tree</subtitle>
<id>https://cgit-dev.freebsd.org/src/atom?h=main</id>
<link rel='self' href='https://cgit-dev.freebsd.org/src/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://cgit-dev.freebsd.org/src/'/>
<updated>2026-07-24T15:07:50Z</updated>
<entry>
<title>uvideo: fix step=0 infinite loop and int overflow in fbuf_size</title>
<updated>2026-07-24T15:07:50Z</updated>
<author>
<name>Baptiste Daroussin</name>
<email>bapt@FreeBSD.org</email>
</author>
<published>2026-07-24T14:30:07Z</published>
<link rel='alternate' type='text/html' href='https://cgit-dev.freebsd.org/src/commit/?id=8468152509a0dfd73e69618af2b1d7f9cbd366f7'/>
<id>urn:sha1:8468152509a0dfd73e69618af2b1d7f9cbd366f7</id>
<content type='text'>
Prevent infinite loop in uvideo_vs_negotiation() when a USB camera reports
step=0 in its continuous frame interval descriptor.
Cast fbuf_size calculation to uint64_t to avoid int overflow for large
width/height/bpp combinations.

Reported by:	emaste
</content>
</entry>
<entry>
<title>uvideo: fix printf type</title>
<updated>2026-07-22T16:37:52Z</updated>
<author>
<name>Baptiste Daroussin</name>
<email>bapt@FreeBSD.org</email>
</author>
<published>2026-07-22T16:37:52Z</published>
<link rel='alternate' type='text/html' href='https://cgit-dev.freebsd.org/src/commit/?id=ba567508718a173e74754d1a010de2f94edd5603'/>
<id>urn:sha1:ba567508718a173e74754d1a010de2f94edd5603</id>
<content type='text'>
Reported by:	vishwin
</content>
</entry>
<entry>
<title>uvideo: validate frame descriptors and fix integer overflows in size computation</title>
<updated>2026-07-22T15:10:58Z</updated>
<author>
<name>Baptiste Daroussin</name>
<email>bapt@FreeBSD.org</email>
</author>
<published>2026-07-22T12:15:21Z</published>
<link rel='alternate' type='text/html' href='https://cgit-dev.freebsd.org/src/commit/?id=c141d75430c75d21aa8260287b9e2a05905335b3'/>
<id>urn:sha1:c141d75430c75d21aa8260287b9e2a05905335b3</id>
<content type='text'>
</content>
</entry>
<entry>
<title>uvideo: use size_t for sc_mmap_count and loop index in reqbufs</title>
<updated>2026-07-22T15:10:58Z</updated>
<author>
<name>Baptiste Daroussin</name>
<email>bapt@FreeBSD.org</email>
</author>
<published>2026-07-22T11:53:34Z</published>
<link rel='alternate' type='text/html' href='https://cgit-dev.freebsd.org/src/commit/?id=599a4d6beff07f93f019e0aff9105a8e642a600f'/>
<id>urn:sha1:599a4d6beff07f93f019e0aff9105a8e642a600f</id>
<content type='text'>
</content>
</entry>
<entry>
<title>uvideo: fix close/detach race on streaming teardown</title>
<updated>2026-07-22T15:10:58Z</updated>
<author>
<name>Baptiste Daroussin</name>
<email>bapt@FreeBSD.org</email>
</author>
<published>2026-07-22T08:18:23Z</published>
<link rel='alternate' type='text/html' href='https://cgit-dev.freebsd.org/src/commit/?id=12b4a02bd88117b07f3e142af71b70bade4fd57e'/>
<id>urn:sha1:12b4a02bd88117b07f3e142af71b70bade4fd57e</id>
<content type='text'>
detach() stopped streaming and called uvideo_vs_close() before
destroy_dev(), so a concurrent close() could race the teardown and call
uvideo_vs_close() a second time (double usbd_transfer_unsetup), and
mtx_destroy() could race a close still holding sc_mtx.  sc_streaming
was also read without the lock in both paths.

Reorder detach() to call destroy_dev() first so all in-flight cdev
methods drain before any teardown.  Read sc_streaming under sc_mtx in
both detach() and the last-close safety net.
</content>
</entry>
<entry>
<title>uvideo: track streaming ownership per-fd and free buffers on STREAMOFF</title>
<updated>2026-07-22T15:10:58Z</updated>
<author>
<name>Baptiste Daroussin</name>
<email>bapt@FreeBSD.org</email>
</author>
<published>2026-07-22T08:14:18Z</published>
<link rel='alternate' type='text/html' href='https://cgit-dev.freebsd.org/src/commit/?id=2120f3e5ec701d92848c259ece4dfbf1aa95f6cb'/>
<id>urn:sha1:2120f3e5ec701d92848c259ece4dfbf1aa95f6cb</id>
<content type='text'>
The driver shared a single streaming state and buffer pool across all
open file descriptors, so a second client (e.g. another browser tab)
could disrupt the first: its cleanup STREAMOFF would tear down the
active stream, and stale buffers prevented re-acquisition.

Add per-fd state via devfs cdevpriv tracking whether this fd started
streaming.  STREAMOFF and close from a non-streaming fd are no-ops.
STREAMOFF from the streaming fd stops the stream and frees the buffers
so that a new fd can re-acquire the camera.  DQBUF returns EPIPE
immediately when buffers are freed instead of waiting for a timeout.
</content>
</entry>
<entry>
<title>uvideo: bounds-check frame interval reads against bLength</title>
<updated>2026-07-22T15:10:57Z</updated>
<author>
<name>Baptiste Daroussin</name>
<email>bapt@FreeBSD.org</email>
</author>
<published>2026-07-22T07:42:29Z</published>
<link rel='alternate' type='text/html' href='https://cgit-dev.freebsd.org/src/commit/?id=cb26bda8ca36e0e421f75d82e1aa46df8f2ff814'/>
<id>urn:sha1:cb26bda8ca36e0e421f75d82e1aa46df8f2ff814</id>
<content type='text'>
Frame interval data is read from device-supplied frame descriptors whose
bLength may be shorter than the number of intervals declared by
bFrameIntervalType.  The continuous branch of uvideo_enum_fivals() read
three intervals unconditionally, and the discrete branch checked the
pointer but not the four bytes that UGETDW() reads, so a short or
malformed descriptor could read past bLength and leak adjacent kernel
memory to userspace.  uvideo_vs_parse_desc_frame_max_rate() had the same
class of off-by-up-to-three-bytes read.

Compute the available bytes from bLength and validate before each read.

Reported by:	emaste
</content>
</entry>
<entry>
<title>uvideo: lock the mmap queue and read path</title>
<updated>2026-07-22T15:10:57Z</updated>
<author>
<name>Baptiste Daroussin</name>
<email>bapt@FreeBSD.org</email>
</author>
<published>2026-07-22T07:26:18Z</published>
<link rel='alternate' type='text/html' href='https://cgit-dev.freebsd.org/src/commit/?id=f12dd1d5f0303fe3bc5030293bda04b04995b72c'/>
<id>urn:sha1:f12dd1d5f0303fe3bc5030293bda04b04995b72c</id>
<content type='text'>
qbuf(), dqbuf() and read() manipulated sc_mmap_q / sc_mmap_cur /
sc_frames_ready without sc_mtx, racing with the USB transfer callbacks
(producer) that run under the mutex.  This could corrupt the queue or
trigger use-after-free.

Take sc_mtx around qbuf(), use mtx_sleep() and protect the queue
operations in dqbuf(), and use mtx_sleep() with a snapshot of sc_fsize
in read().

Also reject S_FMT and S_PARM with EBUSY while streaming: both
re-negotiate the probe/commit controls with the device, which disrupts
the active USB transfers (a second client opening the device would
otherwise freeze the first one's stream).
</content>
</entry>
<entry>
<title>uvideo: validate frame size before mmap buffer allocation</title>
<updated>2026-07-22T15:10:57Z</updated>
<author>
<name>Baptiste Daroussin</name>
<email>bapt@FreeBSD.org</email>
</author>
<published>2026-07-22T07:25:52Z</published>
<link rel='alternate' type='text/html' href='https://cgit-dev.freebsd.org/src/commit/?id=4b9d794b6aa86a2b205e480928552d3f606d9bcc'/>
<id>urn:sha1:4b9d794b6aa86a2b205e480928552d3f606d9bcc</id>
<content type='text'>
dwMaxVideoFrameSize comes from the USB probe/commit response and is not
validated.  reqbufs() computed buf_size_total with signed int arithmetic
and no bound, so a bogus value could wrap the product to a small size
and yield a too-small buffer with a huge sc_mmap_buffer_size, causing
out-of-bounds writes from the USB transfer callbacks.

Bound the frame size against sc_max_fbuf_size and use overflow-checked
size_t arithmetic for the total and per-buffer offsets.

Reported by:	emaste
</content>
</entry>
<entry>
<title>uvideo: replace contigmalloc with OBJT_PHYS vm_object for mmap buffer</title>
<updated>2026-07-22T15:10:57Z</updated>
<author>
<name>Baptiste Daroussin</name>
<email>bapt@FreeBSD.org</email>
</author>
<published>2026-07-22T11:25:31Z</published>
<link rel='alternate' type='text/html' href='https://cgit-dev.freebsd.org/src/commit/?id=4c94869c37e14dc334e2400d1a26d5ded89576fc'/>
<id>urn:sha1:4c94869c37e14dc334e2400d1a26d5ded89576fc</id>
<content type='text'>
Allocate the mmap buffer via phys_pager_allocate() and map it into
kernel space with vm_map_find()/vm_map_wire(), instead of a custom
cdev_pager backed by contigmalloc.  phys_pager_allocate() is required
over a bare vm_object_allocate(OBJT_PHYS) to initialise un_pager.phys.ops,
otherwise phys_pager_getpages() NULL-derefs during vm_map_wire().

Reviewed by:		markj
Reported by:		markj
Differential Revision:	https://reviews.freebsd.org/D58394
</content>
</entry>
</feed>
