]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
media: vivid: s_fbuf: add more sanity checks
authorHans Verkuil <hverkuil-cisco@xs4all.nl>
Wed, 12 Oct 2022 14:32:28 +0000 (15:32 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Tue, 25 Oct 2022 15:38:53 +0000 (16:38 +0100)
VIDIOC_S_FBUF is by definition a scary ioctl, which is why only root
can use it. But at least check if the framebuffer parameters match that
of one of the framebuffer created by vivid, and reject anything else.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Fixes: ef834f7836ec ([media] vivid: add the video capture and output parts)
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/test-drivers/vivid/vivid-core.c
drivers/media/test-drivers/vivid/vivid-core.h
drivers/media/test-drivers/vivid/vivid-vid-cap.c

index 04b75666bad4d5a027fe25544e9b867fb670558e..61d48fbc3d15dd53fd24bc2b824223682db3dc0f 100644 (file)
@@ -339,6 +339,28 @@ static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a
        return vivid_vid_out_g_fbuf(file, fh, a);
 }
 
+/*
+ * Only support the framebuffer of one of the vivid instances.
+ * Anything else is rejected.
+ */
+bool vivid_validate_fb(const struct v4l2_framebuffer *a)
+{
+       struct vivid_dev *dev;
+       int i;
+
+       for (i = 0; i < n_devs; i++) {
+               dev = vivid_devs[i];
+               if (!dev || !dev->video_pbase)
+                       continue;
+               if ((unsigned long)a->base == dev->video_pbase &&
+                   a->fmt.width <= dev->display_width &&
+                   a->fmt.height <= dev->display_height &&
+                   a->fmt.bytesperline <= dev->display_byte_stride)
+                       return true;
+       }
+       return false;
+}
+
 static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a)
 {
        struct video_device *vdev = video_devdata(file);
index bfcfb3515901397b62d26cca5e57092586c9784f..473f3598db5af5198a50e92f2a0688ecb4afb0fe 100644 (file)
@@ -613,4 +613,6 @@ static inline bool vivid_is_hdmi_out(const struct vivid_dev *dev)
        return dev->output_type[dev->output] == HDMI;
 }
 
+bool vivid_validate_fb(const struct v4l2_framebuffer *a);
+
 #endif
index 86b158eeb2d8133ae36bd574145424ae50e35f03..e3e78b5bd22710ce4625cfa62b385ef156271e8e 100644 (file)
@@ -1276,7 +1276,14 @@ int vivid_vid_cap_s_fbuf(struct file *file, void *fh,
                return -EINVAL;
        if (a->fmt.bytesperline < (a->fmt.width * fmt->bit_depth[0]) / 8)
                return -EINVAL;
-       if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage)
+       if (a->fmt.bytesperline > a->fmt.sizeimage / a->fmt.height)
+               return -EINVAL;
+
+       /*
+        * Only support the framebuffer of one of the vivid instances.
+        * Anything else is rejected.
+        */
+       if (!vivid_validate_fb(a))
                return -EINVAL;
 
        dev->fb_vbase_cap = phys_to_virt((unsigned long)a->base);