media: uvcvideo: Silence memcpy() run-time false positive warnings
authorKees Cook <keescook@chromium.org>
Fri, 6 Jan 2023 06:17:04 +0000 (22:17 -0800)
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Sun, 15 Jan 2023 21:45:15 +0000 (23:45 +0200)
The memcpy() in uvc_video_decode_meta() intentionally copies across the
length and flags members and into the trailing buf flexible array.
Split the copy so that the compiler can better reason about (the lack
of) buffer overflows here. Avoid the run-time false positive warning:

  memcpy: detected field-spanning write (size 12) of single field "&meta->length" at drivers/media/usb/uvc/uvc_video.c:1355 (size 1)

Additionally fix a typo in the documentation for struct uvc_meta_buf.

Reported-by: ionut_n2001@yahoo.com
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216810
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
drivers/media/usb/uvc/uvc_video.c
include/uapi/linux/uvcvideo.h

index 98d34d20afe33cd377a93d8d3dae8bcb5dc0c33a..d4b023d4de7c3b37bc0287dce16301e49f4e5bf4 100644 (file)
@@ -1356,7 +1356,9 @@ static void uvc_video_decode_meta(struct uvc_streaming *stream,
        if (has_scr)
                memcpy(stream->clock.last_scr, scr, 6);
 
-       memcpy(&meta->length, mem, length);
+       meta->length = mem[0];
+       meta->flags  = mem[1];
+       memcpy(meta->buf, &mem[2], length - 2);
        meta_buf->bytesused += length + sizeof(meta->ns) + sizeof(meta->sof);
 
        uvc_dbg(stream->dev, FRAME,
index d45d0c2ea25225fbcaf0a7f2712f23e61c33b88b..f86185456dc5b76c4a4460f7ef06c9481b7617f2 100644 (file)
@@ -88,7 +88,7 @@ struct uvc_xu_control_query {
  * struct. The first two fields are added by the driver, they can be used for
  * clock synchronisation. The rest is an exact copy of a UVC payload header.
  * Only complete objects with complete buffers are included. Therefore it's
- * always sizeof(meta->ts) + sizeof(meta->sof) + meta->length bytes large.
+ * always sizeof(meta->ns) + sizeof(meta->sof) + meta->length bytes large.
  */
 struct uvc_meta_buf {
        __u64 ns;