| ad9cc3f1 | 09-Aug-2026 |
Abdelkader Boudih <freebsd@seuros.com> |
uvideo: limit isochronous transfers to 32 frames
Raising UVIDEO_NFRAMES_MAX from 40 to 128 in 3b6f833c95eb improved throughput on xhci but made every camera on an ehci bus fail to stream. Integrated
uvideo: limit isochronous transfers to 32 frames
Raising UVIDEO_NFRAMES_MAX from 40 to 128 in 3b6f833c95eb improved throughput on xhci but made every camera on an ehci bus fail to stream. Integrated webcams became unusable.
Measured on a MacBookPro9,2 with two ehci(4) FaceTime HD cameras and an xhci(4) Logitech C920:
128 32 ehci, 12 captures 0 ok 12 ok xhci 1920x1080 5 fps 5 fps xhci 1280x720 10 fps 10 fps
Fixes: 3b6f833c95eb
Reviewed by: bapt Differential Revision: https://reviews.freebsd.org/D58501
show more ...
|
| 12b4a02b | 22-Jul-2026 |
Baptiste Daroussin <bapt@FreeBSD.org> |
uvideo: fix close/detach race on streaming teardown
detach() stopped streaming and called uvideo_vs_close() before destroy_dev(), so a concurrent close() could race the teardown and call uvideo_vs_c
uvideo: fix close/detach race on streaming teardown
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.
show more ...
|
| 2120f3e5 | 22-Jul-2026 |
Baptiste Daroussin <bapt@FreeBSD.org> |
uvideo: track streaming ownership per-fd and free buffers on STREAMOFF
The driver shared a single streaming state and buffer pool across all open file descriptors, so a second client (e.g. another b
uvideo: track streaming ownership per-fd and free buffers on STREAMOFF
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.
show more ...
|
| cb26bda8 | 22-Jul-2026 |
Baptiste Daroussin <bapt@FreeBSD.org> |
uvideo: bounds-check frame interval reads against bLength
Frame interval data is read from device-supplied frame descriptors whose bLength may be shorter than the number of intervals declared by bFr
uvideo: bounds-check frame interval reads against bLength
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
show more ...
|
| f12dd1d5 | 22-Jul-2026 |
Baptiste Daroussin <bapt@FreeBSD.org> |
uvideo: lock the mmap queue and read path
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
uvideo: lock the mmap queue and read path
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).
show more ...
|
| 4b9d794b | 22-Jul-2026 |
Baptiste Daroussin <bapt@FreeBSD.org> |
uvideo: validate frame size before mmap buffer allocation
dwMaxVideoFrameSize comes from the USB probe/commit response and is not validated. reqbufs() computed buf_size_total with signed int arithm
uvideo: validate frame size before mmap buffer allocation
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
show more ...
|
| a5307a57 | 20-Jul-2026 |
Baptiste Daroussin <bapt@FreeBSD.org> |
uvideo: fix use-after-free in mmap buffer lifetime management
The uvideo driver freed the mmap buffer (contigmalloc'd) in several paths (VIDIOC_STREAMOFF, last close, detach) without coordinating wi
uvideo: fix use-after-free in mmap buffer lifetime management
The uvideo driver freed the mmap buffer (contigmalloc'd) in several paths (VIDIOC_STREAMOFF, last close, detach) without coordinating with the lifetime of existing user-space mmap mappings. This could lead to use-after-free when user-space continued to access the mapped memory after the backing pages had been freed.
Fix this by switching from the simple d_mmap callback to d_mmap_single with custom cdev_pager_ops, and by attaching the contig buffer to a single shared vm_object created at REQBUFS time:
- uvideo_reqbufs() allocates a uvideo_mmap_state (independent of the softc) and a shared vm_object via cdev_pager_allocate() that spans the whole buffer; the softc holds one reference to it. - uvideo_cdev_mmap_single() simply hands out additional references to that shared object; the requested offset selects which buffer is mapped. The VM system tracks mapping lifetime through the object reference count, so no per-mapping bookkeeping is needed. - uvideo_pg_ctor/uvideo_pg_dtor validate the mapping and free the contig buffer together with the state when the last reference (softc's own or a user mapping) is dropped. - uvideo_pg_fault installs a fictitious page for the backing physical address, following the canonical device-pager pattern: update the passed-in page in place when it is already fictitious, otherwise allocate a fake page and vm_page_replace() the busy placeholder, so that dev_pager_dealloc() does not deadlock. - uvideo_vs_free_frame() drops the softc's reference instead of contigfree()'ing directly; if mappings still exist the buffer stays alive until the last uvideo_pg_dtor(). - VIDIOC_STREAMOFF no longer frees the buffer (per V4L2 spec). - Last close always releases the buffer (deferred if mappings exist). - The mmap_state outlives the softc, so the pager dtor can safely free the buffer even after device detach.
Reported by: 章鱼哥 (@aipyapp) (www.aipyaipy.com) Reported by: Chris Jarrett-Davies of the OpenAI Codex Security Team
show more ...
|
| 6e845b13 | 19-Jul-2026 |
Baptiste Daroussin <bapt@FreeBSD.org> |
uvideo: import quirks infrastructure from OpenBSD
Import the device quirk system from OpenBSD to handle UVC devices that need special handling. This includes:
- UVIDEO_FLAG_ISIGHT_STREAM_HEADER: no
uvideo: import quirks infrastructure from OpenBSD
Import the device quirk system from OpenBSD to handle UVC devices that need special handling. This includes:
- UVIDEO_FLAG_ISIGHT_STREAM_HEADER: non-standard streaming header - UVIDEO_FLAG_REATTACH: needs reattach after firmware upload - UVIDEO_FLAG_VENDOR_CLASS: incorrectly reports as vendor class - UVIDEO_FLAG_NOATTACH: device not supported - UVIDEO_FLAG_FORMAT_INDEX_IN_BMHINT: format index in bmHint
Add quirks table with known devices and lookup function. Add iSight stream header decoder for Apple iSight cameras.
Obtained from: OpenBSD
show more ...
|
| 3b6f833c | 18-May-2026 |
Baptiste Daroussin <bapt@FreeBSD.org> |
uvideo: increase isochronous transfer depth for throughput
Increase NFRAMES_MAX from 40 to 128 and IXFERS from 3 to 5 to keep more packets in flight on the USB bus. This brings throughput from ~13.
uvideo: increase isochronous transfer depth for throughput
Increase NFRAMES_MAX from 40 to 128 and IXFERS from 3 to 5 to keep more packets in flight on the USB bus. This brings throughput from ~13.5 MB/s to ~21 MB/s (for comparison on the same camera webcamd provided ~20MB/s.
The linux driver also uses 5 IXFERS (but only 32 NFRAMES_MAX)
Tested by: manu
show more ...
|
| d0450cbe | 06-May-2026 |
Baptiste Daroussin <bapt@FreeBSD.org> |
uvideo: add Camera Terminal controls
Implement UVC Camera Terminal (CT) controls per UVC 1.5 specification Table A-12. This adds support for camera-specific controls that are separate from the Proce
uvideo: add Camera Terminal controls
Implement UVC Camera Terminal (CT) controls per UVC 1.5 specification Table A-12. This adds support for camera-specific controls that are separate from the Processing Unit controls already supported.
Reviewed by: manu Differential Revision: https://reviews.freebsd.org/D56962
show more ...
|
| 54df18cb | 06-May-2026 |
Baptiste Daroussin <bapt@FreeBSD.org> |
uvideo: add kqueue support
Add EVFILT_READ kqueue filter so applications using kqueue/kevent can efficiently wait for video frames instead of polling.
Reviewed by: manu Differential Revision: https
uvideo: add kqueue support
Add EVFILT_READ kqueue filter so applications using kqueue/kevent can efficiently wait for video frames instead of polling.
Reviewed by: manu Differential Revision: https://reviews.freebsd.org/D56961
show more ...
|