V4L/DVB (5163): Add checks for CAP_SYS_ADMIN to VIDIOC_DBG_G_REGISTER

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>
This commit is contained in:
Trent Piepho 2007-01-30 23:25:41 -03:00 committed by Mauro Carvalho Chehab
parent e7b58f5259
commit 62d50addf0
8 changed files with 41 additions and 91 deletions

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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;
}