]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
media: subdev: disallow ioctl for saa6588/davinci
authorArnd Bergmann <arnd@arndb.de>
Mon, 14 Jun 2021 10:34:09 +0000 (12:34 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 20 Jul 2021 14:16:05 +0000 (16:16 +0200)
commit 0a7790be182d32b9b332a37cb4206e24fe94b728 upstream.

The saa6588_ioctl() function expects to get called from other kernel
functions with a 'saa6588_command' pointer, but I found nothing stops it
from getting called from user space instead, which seems rather dangerous.

The same thing happens in the davinci vpbe driver with its VENC_GET_FLD
command.

As a quick fix, add a separate .command() callback pointer for this
driver and change the two callers over to that.  This change can easily
get backported to stable kernels if necessary, but since there are only
two drivers, we may want to eventually replace this with a set of more
specialized callbacks in the long run.

Fixes: c3fda7f835b0 ("V4L/DVB (10537): saa6588: convert to v4l2_subdev.")
Cc: stable@vger.kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/media/i2c/saa6588.c
drivers/media/pci/bt8xx/bttv-driver.c
drivers/media/pci/saa7134/saa7134-video.c
drivers/media/platform/davinci/vpbe_display.c
drivers/media/platform/davinci/vpbe_venc.c
include/media/v4l2-subdev.h

index 33d2987f9555e578c07ac061f1b2136a9a8c88f0..c074e51834e935eaea6216f5b18b7c7f1ac35251 100644 (file)
@@ -392,7 +392,7 @@ static void saa6588_configure(struct saa6588 *s)
 
 /* ---------------------------------------------------------------------- */
 
-static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+static long saa6588_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
        struct saa6588 *s = to_saa6588(sd);
        struct saa6588_command *a = arg;
@@ -445,7 +445,7 @@ static int saa6588_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops saa6588_core_ops = {
-       .ioctl = saa6588_ioctl,
+       .command = saa6588_command,
 };
 
 static const struct v4l2_subdev_tuner_ops saa6588_tuner_ops = {
index 4c042ba6de9187714524453349928e313a96d6e4..2a9d25431d7332e3bcdf399f764deb9ace6858b5 100644 (file)
@@ -3243,7 +3243,7 @@ static int radio_release(struct file *file)
 
        btv->radio_user--;
 
-       bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
+       bttv_call_all(btv, core, command, SAA6588_CMD_CLOSE, &cmd);
 
        if (btv->radio_user == 0)
                btv->has_radio_tuner = 0;
@@ -3324,7 +3324,7 @@ static ssize_t radio_read(struct file *file, char __user *data,
        cmd.result = -ENODEV;
        radio_enable(btv);
 
-       bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd);
+       bttv_call_all(btv, core, command, SAA6588_CMD_READ, &cmd);
 
        return cmd.result;
 }
@@ -3345,7 +3345,7 @@ static __poll_t radio_poll(struct file *file, poll_table *wait)
        cmd.instance = file;
        cmd.event_list = wait;
        cmd.poll_mask = res;
-       bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd);
+       bttv_call_all(btv, core, command, SAA6588_CMD_POLL, &cmd);
 
        return cmd.poll_mask;
 }
index 1a50ec9d084f3d6e78fb50ae818b9330071e4ba2..079219288af7b8b26e37326d413a794bd0cc0401 100644 (file)
@@ -1202,7 +1202,7 @@ static int video_release(struct file *file)
 
        saa_call_all(dev, tuner, standby);
        if (vdev->vfl_type == VFL_TYPE_RADIO)
-               saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
+               saa_call_all(dev, core, command, SAA6588_CMD_CLOSE, &cmd);
        mutex_unlock(&dev->lock);
 
        return 0;
@@ -1221,7 +1221,7 @@ static ssize_t radio_read(struct file *file, char __user *data,
        cmd.result = -ENODEV;
 
        mutex_lock(&dev->lock);
-       saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd);
+       saa_call_all(dev, core, command, SAA6588_CMD_READ, &cmd);
        mutex_unlock(&dev->lock);
 
        return cmd.result;
@@ -1237,7 +1237,7 @@ static __poll_t radio_poll(struct file *file, poll_table *wait)
        cmd.event_list = wait;
        cmd.poll_mask = 0;
        mutex_lock(&dev->lock);
-       saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd);
+       saa_call_all(dev, core, command, SAA6588_CMD_POLL, &cmd);
        mutex_unlock(&dev->lock);
 
        return rc | cmd.poll_mask;
index 6f82693524331e13a5aec76ca4003590c0fb7a4f..2a073a6d83e39e447546a0d8a9e9fcb7a53aaa03 100644 (file)
@@ -60,7 +60,7 @@ static int venc_is_second_field(struct vpbe_display *disp_dev)
 
        ret = v4l2_subdev_call(vpbe_dev->venc,
                               core,
-                              ioctl,
+                              command,
                               VENC_GET_FLD,
                               &val);
        if (ret < 0) {
index ddcad7b3e76c21d07609a3938e401052940f853a..c2cfaa9c695779fdd692ea8fe2789c0d9e840c9a 100644 (file)
@@ -534,9 +534,7 @@ static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
        return ret;
 }
 
-static long venc_ioctl(struct v4l2_subdev *sd,
-                       unsigned int cmd,
-                       void *arg)
+static long venc_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
        u32 val;
 
@@ -555,7 +553,7 @@ static long venc_ioctl(struct v4l2_subdev *sd,
 }
 
 static const struct v4l2_subdev_core_ops venc_core_ops = {
-       .ioctl      = venc_ioctl,
+       .command      = venc_command,
 };
 
 static const struct v4l2_subdev_video_ops venc_video_ops = {
index 9102d6ca566e01f271935131bc95409126ca1aa9..eac37dd3e3bae8612fcebee1230a6476421fe01f 100644 (file)
@@ -171,6 +171,9 @@ struct v4l2_subdev_io_pin_config {
  * @s_gpio: set GPIO pins. Very simple right now, might need to be extended with
  *     a direction argument if needed.
  *
+ * @command: called by in-kernel drivers in order to call functions internal
+ *        to subdev drivers driver that have a separate callback.
+ *
  * @ioctl: called at the end of ioctl() syscall handler at the V4L2 core.
  *        used to provide support for private ioctls used on the driver.
  *
@@ -202,6 +205,7 @@ struct v4l2_subdev_core_ops {
        int (*load_fw)(struct v4l2_subdev *sd);
        int (*reset)(struct v4l2_subdev *sd, u32 val);
        int (*s_gpio)(struct v4l2_subdev *sd, u32 val);
+       long (*command)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
        long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
 #ifdef CONFIG_COMPAT
        long (*compat_ioctl32)(struct v4l2_subdev *sd, unsigned int cmd,