summaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJanusz Krzysztofik <jmkrzyszt@gmail.com>2019-05-20 17:27:47 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-06-24 14:55:20 -0400
commit374d62e7aa50f66c1a4316be9221df4d0f38addd (patch)
tree939548f0f424cf5fad4c88d436d6c22b5a357efa /drivers/media
parenta4f4a763d8a01d0f461e3b8c4774ed45e9ded5f4 (diff)
media: v4l2-subdev: Verify v4l2_subdev_call() pad config argument
Extend parameter checks performed by v4l2_subdev_call() with a check for a non-NULL pad config pointer if V4L2_SUBDEV_FORMAT_TRY format type is requested so drivers don't need to care. Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com> Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 4036d30450d3..21fb90d66bfc 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -136,20 +136,30 @@ static inline int check_pad(struct v4l2_subdev *sd, __u32 pad)
136 return 0; 136 return 0;
137} 137}
138 138
139static int check_cfg(__u32 which, struct v4l2_subdev_pad_config *cfg)
140{
141 if (which == V4L2_SUBDEV_FORMAT_TRY && !cfg)
142 return -EINVAL;
143
144 return 0;
145}
146
139static inline int check_format(struct v4l2_subdev *sd, 147static inline int check_format(struct v4l2_subdev *sd,
148 struct v4l2_subdev_pad_config *cfg,
140 struct v4l2_subdev_format *format) 149 struct v4l2_subdev_format *format)
141{ 150{
142 if (!format) 151 if (!format)
143 return -EINVAL; 152 return -EINVAL;
144 153
145 return check_which(format->which) ? : check_pad(sd, format->pad); 154 return check_which(format->which) ? : check_pad(sd, format->pad) ? :
155 check_cfg(format->which, cfg);
146} 156}
147 157
148static int call_get_fmt(struct v4l2_subdev *sd, 158static int call_get_fmt(struct v4l2_subdev *sd,
149 struct v4l2_subdev_pad_config *cfg, 159 struct v4l2_subdev_pad_config *cfg,
150 struct v4l2_subdev_format *format) 160 struct v4l2_subdev_format *format)
151{ 161{
152 return check_format(sd, format) ? : 162 return check_format(sd, cfg, format) ? :
153 sd->ops->pad->get_fmt(sd, cfg, format); 163 sd->ops->pad->get_fmt(sd, cfg, format);
154} 164}
155 165
@@ -157,7 +167,7 @@ static int call_set_fmt(struct v4l2_subdev *sd,
157 struct v4l2_subdev_pad_config *cfg, 167 struct v4l2_subdev_pad_config *cfg,
158 struct v4l2_subdev_format *format) 168 struct v4l2_subdev_format *format)
159{ 169{
160 return check_format(sd, format) ? : 170 return check_format(sd, cfg, format) ? :
161 sd->ops->pad->set_fmt(sd, cfg, format); 171 sd->ops->pad->set_fmt(sd, cfg, format);
162} 172}
163 173
@@ -169,6 +179,7 @@ static int call_enum_mbus_code(struct v4l2_subdev *sd,
169 return -EINVAL; 179 return -EINVAL;
170 180
171 return check_which(code->which) ? : check_pad(sd, code->pad) ? : 181 return check_which(code->which) ? : check_pad(sd, code->pad) ? :
182 check_cfg(code->which, cfg) ? :
172 sd->ops->pad->enum_mbus_code(sd, cfg, code); 183 sd->ops->pad->enum_mbus_code(sd, cfg, code);
173} 184}
174 185
@@ -180,6 +191,7 @@ static int call_enum_frame_size(struct v4l2_subdev *sd,
180 return -EINVAL; 191 return -EINVAL;
181 192
182 return check_which(fse->which) ? : check_pad(sd, fse->pad) ? : 193 return check_which(fse->which) ? : check_pad(sd, fse->pad) ? :
194 check_cfg(fse->which, cfg) ? :
183 sd->ops->pad->enum_frame_size(sd, cfg, fse); 195 sd->ops->pad->enum_frame_size(sd, cfg, fse);
184} 196}
185 197
@@ -214,23 +226,26 @@ static int call_enum_frame_interval(struct v4l2_subdev *sd,
214 return -EINVAL; 226 return -EINVAL;
215 227
216 return check_which(fie->which) ? : check_pad(sd, fie->pad) ? : 228 return check_which(fie->which) ? : check_pad(sd, fie->pad) ? :
229 check_cfg(fie->which, cfg) ? :
217 sd->ops->pad->enum_frame_interval(sd, cfg, fie); 230 sd->ops->pad->enum_frame_interval(sd, cfg, fie);
218} 231}
219 232
220static inline int check_selection(struct v4l2_subdev *sd, 233static inline int check_selection(struct v4l2_subdev *sd,
234 struct v4l2_subdev_pad_config *cfg,
221 struct v4l2_subdev_selection *sel) 235 struct v4l2_subdev_selection *sel)
222{ 236{
223 if (!sel) 237 if (!sel)
224 return -EINVAL; 238 return -EINVAL;
225 239
226 return check_which(sel->which) ? : check_pad(sd, sel->pad); 240 return check_which(sel->which) ? : check_pad(sd, sel->pad) ? :
241 check_cfg(sel->which, cfg);
227} 242}
228 243
229static int call_get_selection(struct v4l2_subdev *sd, 244static int call_get_selection(struct v4l2_subdev *sd,
230 struct v4l2_subdev_pad_config *cfg, 245 struct v4l2_subdev_pad_config *cfg,
231 struct v4l2_subdev_selection *sel) 246 struct v4l2_subdev_selection *sel)
232{ 247{
233 return check_selection(sd, sel) ? : 248 return check_selection(sd, cfg, sel) ? :
234 sd->ops->pad->get_selection(sd, cfg, sel); 249 sd->ops->pad->get_selection(sd, cfg, sel);
235} 250}
236 251
@@ -238,7 +253,7 @@ static int call_set_selection(struct v4l2_subdev *sd,
238 struct v4l2_subdev_pad_config *cfg, 253 struct v4l2_subdev_pad_config *cfg,
239 struct v4l2_subdev_selection *sel) 254 struct v4l2_subdev_selection *sel)
240{ 255{
241 return check_selection(sd, sel) ? : 256 return check_selection(sd, cfg, sel) ? :
242 sd->ops->pad->set_selection(sd, cfg, sel); 257 sd->ops->pad->set_selection(sd, cfg, sel);
243} 258}
244 259