aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/media/usb/uvc/uvc_ctrl.c
diff options
context:
space:
mode:
authorRicardo Ribalda <ribalda@chromium.org>2021-06-18 14:29:16 +0200
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2021-09-30 10:07:48 +0200
commitee929d5a10ca433a1c21b9aaeb70a67c5507c101 (patch)
tree28485369305ce85389d28df090fc4e278974a373 /drivers/media/usb/uvc/uvc_ctrl.c
parentmedia: uvcvideo: Use control names from framework (diff)
downloadwireguard-linux-ee929d5a10ca433a1c21b9aaeb70a67c5507c101.tar.xz
wireguard-linux-ee929d5a10ca433a1c21b9aaeb70a67c5507c101.zip
media: uvcvideo: Check controls flags before accessing them
We can figure out if reading/writing a set of controls can fail without accessing them by checking their flags. This way we can honor the API closer: If an error is found when validating the list of controls passed with VIDIOC_G_EXT_CTRLS, then error_idx shall be set to ctrls->count to indicate to userspace that no actual hardware was touched. Fixes v4l2-compliance: Control ioctls (Input 0): warn: v4l2-test-controls.cpp(765): g_ext_ctrls(0) invalid error_idx 0 fail: v4l2-test-controls.cpp(645): invalid error index write only control test VIDIOC_G/S/TRY_EXT_CTRLS: FAIL Reviewed-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media/usb/uvc/uvc_ctrl.c')
-rw-r--r--drivers/media/usb/uvc/uvc_ctrl.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index 2cc2ff0d0cae..18c315b52ef5 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -1042,6 +1042,28 @@ static int uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id,
return 0;
}
+int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
+ bool read)
+{
+ struct uvc_control_mapping *mapping;
+ struct uvc_control *ctrl;
+
+ if (__uvc_query_v4l2_class(chain, v4l2_id, 0) >= 0)
+ return -EACCES;
+
+ ctrl = uvc_find_control(chain, v4l2_id, &mapping);
+ if (!ctrl)
+ return -EINVAL;
+
+ if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) && read)
+ return -EACCES;
+
+ if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) && !read)
+ return -EACCES;
+
+ return 0;
+}
+
static const char *uvc_map_get_name(const struct uvc_control_mapping *map)
{
const char *name;