Skip to content

Commit

Permalink
[media] v4l: subdev: Unify argument validation across IOCTLs
Browse files Browse the repository at this point in the history
Separate validation of different argument types. There's no reason to do
this separately for every IOCTL.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
  • Loading branch information
Sakari Ailus authored and Mauro Carvalho Chehab committed Jul 22, 2014
1 parent 6c5bba9 commit b225e39
Showing 1 changed file with 74 additions and 46 deletions.
120 changes: 74 additions & 46 deletions drivers/media/v4l2-core/v4l2-subdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,55 @@ static int subdev_close(struct file *file)
return 0;
}

static int check_format(struct v4l2_subdev *sd,
struct v4l2_subdev_format *format)
{
if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;

if (format->pad >= sd->entity.num_pads)
return -EINVAL;

return 0;
}

static int check_crop(struct v4l2_subdev *sd, struct v4l2_subdev_crop *crop)
{
if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;

if (crop->pad >= sd->entity.num_pads)
return -EINVAL;

return 0;
}

static int check_selection(struct v4l2_subdev *sd,
struct v4l2_subdev_selection *sel)
{
if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;

if (sel->pad >= sd->entity.num_pads)
return -EINVAL;

return 0;
}

static int check_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
{
if (edid->pad >= sd->entity.num_pads)
return -EINVAL;

if (edid->blocks && edid->edid == NULL)
return -EINVAL;

return 0;
}

static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct video_device *vdev = video_devdata(file);
Expand All @@ -134,6 +183,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
#endif
int rval;

switch (cmd) {
case VIDIOC_QUERYCTRL:
Expand Down Expand Up @@ -206,40 +256,30 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_SUBDEV_G_FMT: {
struct v4l2_subdev_format *format = arg;

if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;

if (format->pad >= sd->entity.num_pads)
return -EINVAL;
rval = check_format(sd, format);
if (rval)
return rval;

return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh, format);
}

case VIDIOC_SUBDEV_S_FMT: {
struct v4l2_subdev_format *format = arg;

if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;

if (format->pad >= sd->entity.num_pads)
return -EINVAL;
rval = check_format(sd, format);
if (rval)
return rval;

return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format);
}

case VIDIOC_SUBDEV_G_CROP: {
struct v4l2_subdev_crop *crop = arg;
struct v4l2_subdev_selection sel;
int rval;

if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;

if (crop->pad >= sd->entity.num_pads)
return -EINVAL;
rval = check_crop(sd, crop);
if (rval)
return rval;

rval = v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
if (rval != -ENOIOCTLCMD)
Expand All @@ -261,14 +301,10 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_SUBDEV_S_CROP: {
struct v4l2_subdev_crop *crop = arg;
struct v4l2_subdev_selection sel;
int rval;

if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;

if (crop->pad >= sd->entity.num_pads)
return -EINVAL;
rval = check_crop(sd, crop);
if (rval)
return rval;

rval = v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
if (rval != -ENOIOCTLCMD)
Expand Down Expand Up @@ -339,12 +375,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_SUBDEV_G_SELECTION: {
struct v4l2_subdev_selection *sel = arg;

if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;

if (sel->pad >= sd->entity.num_pads)
return -EINVAL;
rval = check_selection(sd, sel);
if (rval)
return rval;

return v4l2_subdev_call(
sd, pad, get_selection, subdev_fh, sel);
Expand All @@ -353,12 +386,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_SUBDEV_S_SELECTION: {
struct v4l2_subdev_selection *sel = arg;

if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;

if (sel->pad >= sd->entity.num_pads)
return -EINVAL;
rval = check_selection(sd, sel);
if (rval)
return rval;

return v4l2_subdev_call(
sd, pad, set_selection, subdev_fh, sel);
Expand All @@ -367,21 +397,19 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_G_EDID: {
struct v4l2_subdev_edid *edid = arg;

if (edid->pad >= sd->entity.num_pads)
return -EINVAL;
if (edid->blocks && edid->edid == NULL)
return -EINVAL;
rval = check_edid(sd, edid);
if (rval)
return rval;

return v4l2_subdev_call(sd, pad, get_edid, edid);
}

case VIDIOC_S_EDID: {
struct v4l2_subdev_edid *edid = arg;

if (edid->pad >= sd->entity.num_pads)
return -EINVAL;
if (edid->blocks && edid->edid == NULL)
return -EINVAL;
rval = check_edid(sd, edid);
if (rval)
return rval;

return v4l2_subdev_call(sd, pad, set_edid, edid);
}
Expand Down

0 comments on commit b225e39

Please sign in to comment.