Date: Wed, 22 Jul 2026 15:12:46 +0000 From: Baptiste Daroussin <bapt@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 4b9d794b6aa8 - main - uvideo: validate frame size before mmap buffer allocation Message-ID: <6a60ddee.34719.708b084f@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by bapt: URL: https://cgit.FreeBSD.org/src/commit/?id=4b9d794b6aa86a2b205e480928552d3f606d9bcc commit 4b9d794b6aa86a2b205e480928552d3f606d9bcc Author: Baptiste Daroussin <bapt@FreeBSD.org> AuthorDate: 2026-07-22 07:25:52 +0000 Commit: Baptiste Daroussin <bapt@FreeBSD.org> CommitDate: 2026-07-22 15:10:57 +0000 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 --- sys/dev/usb/video/uvideo.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sys/dev/usb/video/uvideo.c b/sys/dev/usb/video/uvideo.c index bb4d42778998..9c6076bc76d0 100644 --- a/sys/dev/usb/video/uvideo.c +++ b/sys/dev/usb/video/uvideo.c @@ -3531,7 +3531,9 @@ uvideo_g_input(struct uvideo_softc *sc, int *input) static int uvideo_reqbufs(struct uvideo_softc *sc, struct v4l2_requestbuffers *rb) { - int i, buf_size, buf_size_total; + int i; + uint32_t buf_size; + size_t buf_size_total; vm_object_t obj; vm_offset_t kva; int error; @@ -3552,7 +3554,12 @@ uvideo_reqbufs(struct uvideo_softc *sc, struct v4l2_requestbuffers *rb) sc->sc_mmap_count = rb->count; buf_size = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize); - buf_size_total = sc->sc_mmap_count * buf_size; + if (buf_size == 0 || sc->sc_max_fbuf_size <= 0 || + buf_size > (u_int)sc->sc_max_fbuf_size) + return (EINVAL); + if (SIZE_MAX / sc->sc_mmap_count < buf_size) + return (EINVAL); + buf_size_total = (size_t)sc->sc_mmap_count * buf_size; buf_size_total = round_page(buf_size_total); /* @@ -3599,10 +3606,11 @@ uvideo_reqbufs(struct uvideo_softc *sc, struct v4l2_requestbuffers *rb) buf_size_total, (uintmax_t)kva); for (i = 0; i < sc->sc_mmap_count; i++) { - sc->sc_mmap[i].buf = sc->sc_mmap_buffer + (i * buf_size); + sc->sc_mmap[i].buf = sc->sc_mmap_buffer + + ((size_t)i * buf_size); sc->sc_mmap[i].v4l2_buf.index = i; - sc->sc_mmap[i].v4l2_buf.m.offset = i * buf_size; + sc->sc_mmap[i].v4l2_buf.m.offset = (size_t)i * buf_size; sc->sc_mmap[i].v4l2_buf.length = buf_size; sc->sc_mmap[i].v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; sc->sc_mmap[i].v4l2_buf.sequence = 0;home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a60ddee.34719.708b084f>
