V4L/DVB (5163): Add checks for CAP_SYS_ADMIN to VIDIOC_DBG_G_REGISTER
authorTrent Piepho <xyzzy@speakeasy.org>
Wed, 31 Jan 2007 02:25:41 +0000 (23:25 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Wed, 21 Feb 2007 15:35:10 +0000 (13:35 -0200)
Before, root privileges were only needed to set hardware registers, not
to read them.  On some hardware, reading from the wrong place at the
wrong time can hang the machine.  So, to be consistent, root privileges
are required to read registers on all hardware.

Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/cx25840/cx25840-core.c
drivers/media/video/saa7115.c
drivers/media/video/saa7127.c
drivers/media/video/tvp5150.c
drivers/media/video/upd64031a.c
drivers/media/video/upd64083.c
drivers/media/video/usbvision/usbvision-video.c
drivers/media/video/videodev.c

index 6515b2a784173d4e6b1c719abeba5beb3216f237..9235777232979f32ff8dc7dd1d02c1f29dc2f3e6 100644 (file)
@@ -629,15 +629,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
        /* ioctls to allow direct access to the
         * cx25840 registers for testing */
        case VIDIOC_DBG_G_REGISTER:
-       {
-               struct v4l2_register *reg = arg;
-
-               if (reg->i2c_id != I2C_DRIVERID_CX25840)
-                       return -EINVAL;
-               reg->val = cx25840_read(client, reg->reg & 0x0fff);
-               break;
-       }
-
        case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *reg = arg;
@@ -646,7 +637,10 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
+               if (cmd == VIDIOC_DBG_G_REGISTER)
+                       reg->val = cx25840_read(client, reg->reg & 0x0fff);
+               else
+                       cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
                break;
        }
 #endif
index bb6aa135002a20e4636ef378f768084f5a3b53c3..71777216b607afcb1775e69023d1b6807b32666f 100644 (file)
@@ -1418,15 +1418,6 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        case VIDIOC_DBG_G_REGISTER:
-       {
-               struct v4l2_register *reg = arg;
-
-               if (reg->i2c_id != I2C_DRIVERID_SAA711X)
-                       return -EINVAL;
-               reg->val = saa711x_read(client, reg->reg & 0xff);
-               break;
-       }
-
        case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *reg = arg;
@@ -1435,7 +1426,10 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               saa711x_write(client, reg->reg & 0xff, reg->val & 0xff);
+               if (cmd == VIDIOC_DBG_G_REGISTER)
+                       reg->val = saa711x_read(client, reg->reg & 0xff);
+               else
+                       saa711x_write(client, reg->reg & 0xff, reg->val & 0xff);
                break;
        }
 #endif
index 304375ade4a9aed6c6dc1468ceb41529af6317e0..bd9c4f3ad02ee34a3a25ed19da3d7de00eef6380 100644 (file)
@@ -615,15 +615,6 @@ static int saa7127_command(struct i2c_client *client,
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        case VIDIOC_DBG_G_REGISTER:
-       {
-               struct v4l2_register *reg = arg;
-
-               if (reg->i2c_id != I2C_DRIVERID_SAA7127)
-                       return -EINVAL;
-               reg->val = saa7127_read(client, reg->reg & 0xff);
-               break;
-       }
-
        case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *reg = arg;
@@ -632,7 +623,10 @@ static int saa7127_command(struct i2c_client *client,
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
+               if (cmd == VIDIOC_DBG_G_REGISTER)
+                       reg->val = saa7127_read(client, reg->reg & 0xff);
+               else
+                       saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
                break;
        }
 #endif
index 65d4389690a044a161cb7670e682987042058b35..886b5df7c9d146610d4410057e49eb0e37282965 100644 (file)
@@ -951,15 +951,6 @@ static int tvp5150_command(struct i2c_client *c,
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        case VIDIOC_DBG_G_REGISTER:
-       {
-               struct v4l2_register *reg = arg;
-
-               if (reg->i2c_id != I2C_DRIVERID_TVP5150)
-                       return -EINVAL;
-               reg->val = tvp5150_read(c, reg->reg & 0xff);
-               break;
-       }
-
        case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *reg = arg;
@@ -968,7 +959,10 @@ static int tvp5150_command(struct i2c_client *c,
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               tvp5150_write(c, reg->reg & 0xff, reg->val & 0xff);
+               if (cmd == VIDIOC_DBG_G_REGISTER)
+                       reg->val = tvp5150_read(c, reg->reg & 0xff);
+               else
+                       tvp5150_write(c, reg->reg & 0xff, reg->val & 0xff);
                break;
        }
 #endif
index 0eee82ba52bc127111f8ac32c04a2c31aae8fedf..b3b5fd536dc3c89b884d5e5480c04b2752347d5a 100644 (file)
@@ -163,26 +163,18 @@ static int upd64031a_command(struct i2c_client *client, unsigned int cmd, void *
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        case VIDIOC_DBG_G_REGISTER:
-       {
-               struct v4l2_register *reg = arg;
-
-               if (reg->i2c_id != I2C_DRIVERID_UPD64031A)
-                       return -EINVAL;
-               reg->val = upd64031a_read(client, reg->reg & 0xff);
-               break;
-       }
-
        case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *reg = arg;
-               u8 addr = reg->reg & 0xff;
-               u8 val = reg->val & 0xff;
 
                if (reg->i2c_id != I2C_DRIVERID_UPD64031A)
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               upd64031a_write(client, addr, val);
+               if (cmd == VIDIOC_DBG_G_REGISTER)
+                       reg->val = upd64031a_read(client, reg->reg & 0xff);
+               else
+                       upd64031a_write(client, reg->reg & 0xff, reg->val & 0xff);
                break;
        }
 #endif
index 3f0eec0cdb45fd580bb9cc9b2948acd5551e0822..8852903e7a92dba432d4af40fc2d8ab517e5b166 100644 (file)
@@ -140,26 +140,18 @@ static int upd64083_command(struct i2c_client *client, unsigned int cmd, void *a
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        case VIDIOC_DBG_G_REGISTER:
-       {
-               struct v4l2_register *reg = arg;
-
-               if (reg->i2c_id != I2C_DRIVERID_UPD64083)
-                       return -EINVAL;
-               reg->val = upd64083_read(client, reg->reg & 0xff);
-               break;
-       }
-
        case VIDIOC_DBG_S_REGISTER:
        {
                struct v4l2_register *reg = arg;
-               u8 addr = reg->reg & 0xff;
-               u8 val = reg->val & 0xff;
 
                if (reg->i2c_id != I2C_DRIVERID_UPD64083)
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               upd64083_write(client, addr, val);
+               if (cmd == VIDIOC_DBG_G_REGISTER)
+                       reg->val = upd64083_read(client, reg->reg & 0xff);
+               else
+                       upd64083_write(client, reg->reg & 0xff, reg->val & 0xff);
                break;
        }
 #endif
index b6fabeeb8ab8c7e7e3e86c1ab8de3b714854b3c8..6a61ebcdf130d7fdca39fa2f9201fc334caa3ec9 100644 (file)
@@ -520,25 +520,6 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
                /* ioctls to allow direct acces to the NT100x registers */
                case VIDIOC_DBG_G_REGISTER:
-               {
-                       struct v4l2_register *reg = arg;
-                       int errCode;
-
-                       if (reg->i2c_id != 0)
-                               return -EINVAL;
-                       /* NT100x has a 8-bit register space */
-                       errCode = usbvision_read_reg(usbvision, reg->reg&0xff);
-                       if (errCode < 0) {
-                               err("%s: VIDIOC_DBG_G_REGISTER failed: error %d", __FUNCTION__, errCode);
-                       }
-                       else {
-                               reg->val=(unsigned char)errCode;
-                               PDEBUG(DBG_IOCTL, "VIDIOC_DBG_G_REGISTER reg=0x%02X, value=0x%02X",
-                                                       (unsigned int)reg->reg, reg->val);
-                               errCode = 0; // No error
-                       }
-                       return errCode;
-               }
                case VIDIOC_DBG_S_REGISTER:
                {
                        struct v4l2_register *reg = arg;
@@ -548,15 +529,22 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
                                return -EINVAL;
                        if (!capable(CAP_SYS_ADMIN))
                                return -EPERM;
-                       errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
+                       /* NT100x has a 8-bit register space */
+                       if (cmd == VIDIOC_DBG_G_REGISTER)
+                               errCode = usbvision_read_reg(usbvision, reg->reg&0xff);
+                       else
+                               errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
                        if (errCode < 0) {
-                               err("%s: VIDIOC_DBG_S_REGISTER failed: error %d", __FUNCTION__, errCode);
-                       }
-                       else {
-                               PDEBUG(DBG_IOCTL, "VIDIOC_DBG_S_REGISTER reg=0x%02X, value=0x%02X",
-                                                       (unsigned int)reg->reg, reg->val);
-                               errCode = 0;
+                               err("%s: VIDIOC_DBG_%c_REGISTER failed: error %d", __FUNCTION__,
+                                   cmd == VIDIOC_DBG_G_REGISTER ? 'G' : 'S', errCode);
+                               return errCode;
                        }
+                       if (cmd == VIDIOC_DBG_S_REGISTER)
+                               reg->val = (u8)errCode;
+
+                       PDEBUG(DBG_IOCTL, "VIDIOC_DBG_%c_REGISTER reg=0x%02X, value=0x%02X",
+                              cmd == VIDIOC_DBG_G_REGISTER ? 'G' : 'S',
+                              (unsigned int)reg->reg, reg->val);
                        return 0;
                }
 #endif
index 764a53b70db24ae31b8076b969668cb195bb6235..dc9b1ef678aa01a79b34736596b60d44a8e055f3 100644 (file)
@@ -1457,7 +1457,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
        case VIDIOC_DBG_G_REGISTER:
        {
                struct v4l2_register *p=arg;
-               if (vfd->vidioc_g_register)
+               if (!capable(CAP_SYS_ADMIN))
+                       ret=-EPERM;
+               else if (vfd->vidioc_g_register)
                        ret=vfd->vidioc_g_register(file, fh, p);
                break;
        }