aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2014-01-29 08:07:13 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-25 11:48:33 -0400
commitf2e9084779d3ad3b51ee45a3a53fead3f16516ca (patch)
tree79dc867b483e692582d373e41e5840adf602f1eb /drivers/media
parent9cfd65e80959836fed78704e8a127d4e10448d56 (diff)
[media] v4l: Validate fields in the core code for subdev EDID ioctls
The subdev EDID ioctls receive a pad field that must reference an existing pad and an EDID field that must point to a buffer. Validate both fields in the core code instead of duplicating validation in all drivers. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com> Reviewed-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/i2c/ad9389b.c2
-rw-r--r--drivers/media/i2c/adv7511.c2
-rw-r--r--drivers/media/i2c/adv7604.c4
-rw-r--r--drivers/media/i2c/adv7842.c4
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c24
5 files changed, 20 insertions, 16 deletions
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c
index f00b3dd2b457..fada17566205 100644
--- a/drivers/media/i2c/ad9389b.c
+++ b/drivers/media/i2c/ad9389b.c
@@ -682,8 +682,6 @@ static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
682 return -EINVAL; 682 return -EINVAL;
683 if (edid->blocks == 0 || edid->blocks > 256) 683 if (edid->blocks == 0 || edid->blocks > 256)
684 return -EINVAL; 684 return -EINVAL;
685 if (!edid->edid)
686 return -EINVAL;
687 if (!state->edid.segments) { 685 if (!state->edid.segments) {
688 v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n"); 686 v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
689 return -ENODATA; 687 return -ENODATA;
diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c
index d77a1db4f94d..f98acf4aafd4 100644
--- a/drivers/media/i2c/adv7511.c
+++ b/drivers/media/i2c/adv7511.c
@@ -783,8 +783,6 @@ static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
783 return -EINVAL; 783 return -EINVAL;
784 if ((edid->blocks == 0) || (edid->blocks > 256)) 784 if ((edid->blocks == 0) || (edid->blocks > 256))
785 return -EINVAL; 785 return -EINVAL;
786 if (!edid->edid)
787 return -EINVAL;
788 if (!state->edid.segments) { 786 if (!state->edid.segments) {
789 v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n"); 787 v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
790 return -ENODATA; 788 return -ENODATA;
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 98cc5407f1b1..338baa4c23ef 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -1673,8 +1673,6 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
1673 return -EINVAL; 1673 return -EINVAL;
1674 if (edid->start_block == 1) 1674 if (edid->start_block == 1)
1675 edid->blocks = 1; 1675 edid->blocks = 1;
1676 if (!edid->edid)
1677 return -EINVAL;
1678 1676
1679 if (edid->blocks > state->edid.blocks) 1677 if (edid->blocks > state->edid.blocks)
1680 edid->blocks = state->edid.blocks; 1678 edid->blocks = state->edid.blocks;
@@ -1761,8 +1759,6 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
1761 edid->blocks = 2; 1759 edid->blocks = 2;
1762 return -E2BIG; 1760 return -E2BIG;
1763 } 1761 }
1764 if (!edid->edid)
1765 return -EINVAL;
1766 1762
1767 v4l2_dbg(2, debug, sd, "%s: write EDID pad %d, edid.present = 0x%x\n", 1763 v4l2_dbg(2, debug, sd, "%s: write EDID pad %d, edid.present = 0x%x\n",
1768 __func__, edid->pad, state->edid.present); 1764 __func__, edid->pad, state->edid.present);
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index d85e125aa8d8..0d554919cdd5 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -2036,8 +2036,6 @@ static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
2036 return -EINVAL; 2036 return -EINVAL;
2037 if (edid->start_block == 1) 2037 if (edid->start_block == 1)
2038 edid->blocks = 1; 2038 edid->blocks = 1;
2039 if (!edid->edid)
2040 return -EINVAL;
2041 2039
2042 switch (edid->pad) { 2040 switch (edid->pad) {
2043 case ADV7842_EDID_PORT_A: 2041 case ADV7842_EDID_PORT_A:
@@ -2072,8 +2070,6 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e)
2072 return -EINVAL; 2070 return -EINVAL;
2073 if (e->blocks > 2) 2071 if (e->blocks > 2)
2074 return -E2BIG; 2072 return -E2BIG;
2075 if (!e->edid)
2076 return -EINVAL;
2077 2073
2078 /* todo, per edid */ 2074 /* todo, per edid */
2079 state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15], 2075 state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15],
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index db126dbc19c9..058c1a6e8392 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -361,11 +361,27 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
361 sd, pad, set_selection, subdev_fh, sel); 361 sd, pad, set_selection, subdev_fh, sel);
362 } 362 }
363 363
364 case VIDIOC_G_EDID: 364 case VIDIOC_G_EDID: {
365 return v4l2_subdev_call(sd, pad, get_edid, arg); 365 struct v4l2_subdev_edid *edid = arg;
366 366
367 case VIDIOC_S_EDID: 367 if (edid->pad >= sd->entity.num_pads)
368 return v4l2_subdev_call(sd, pad, set_edid, arg); 368 return -EINVAL;
369 if (edid->blocks && edid->edid == NULL)
370 return -EINVAL;
371
372 return v4l2_subdev_call(sd, pad, get_edid, edid);
373 }
374
375 case VIDIOC_S_EDID: {
376 struct v4l2_subdev_edid *edid = arg;
377
378 if (edid->pad >= sd->entity.num_pads)
379 return -EINVAL;
380 if (edid->blocks && edid->edid == NULL)
381 return -EINVAL;
382
383 return v4l2_subdev_call(sd, pad, set_edid, edid);
384 }
369 385
370 case VIDIOC_SUBDEV_DV_TIMINGS_CAP: { 386 case VIDIOC_SUBDEV_DV_TIMINGS_CAP: {
371 struct v4l2_dv_timings_cap *cap = arg; 387 struct v4l2_dv_timings_cap *cap = arg;