All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Ricardo Ribalda <ribalda@chromium.org>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>,
	Hans Verkuil <hverkuil-cisco@xs4all.nl>,
	Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
	linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
	tfiga@chromium.org
Subject: Re: [PATCH v9 14/22] media: uvcvideo: Check controls flags before accessing them
Date: Thu, 10 Jun 2021 19:55:38 +0300	[thread overview]
Message-ID: <YMJECjaaoqDWmnPL@pendragon.ideasonboard.com> (raw)
In-Reply-To: <20210326095840.364424-15-ribalda@chromium.org>

Hi Ricardo,

Thank you for the patch.

On Fri, Mar 26, 2021 at 10:58:32AM +0100, Ricardo Ribalda wrote:
> 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>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  drivers/media/usb/uvc/uvc_ctrl.c | 22 ++++++++++++++++++
>  drivers/media/usb/uvc/uvc_v4l2.c | 39 ++++++++++++++++++++++++++++----
>  drivers/media/usb/uvc/uvcvideo.h |  2 ++
>  3 files changed, 58 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> index 929e70dff11a..24fd5afc4e4f 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -1046,6 +1046,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;
> diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
> index 28ccaa8b9e42..a3ee1dc003fc 100644
> --- a/drivers/media/usb/uvc/uvc_v4l2.c
> +++ b/drivers/media/usb/uvc/uvc_v4l2.c
> @@ -991,6 +991,26 @@ static int uvc_ioctl_query_ext_ctrl(struct file *file, void *fh,
>  	return 0;
>  }
>  
> +static int uvc_ctrl_check_access(struct uvc_video_chain *chain,
> +				 struct v4l2_ext_controls *ctrls,
> +				 unsigned long ioctl)
> +{
> +	struct v4l2_ext_control *ctrl = ctrls->controls;
> +	unsigned int i;
> +	int ret = 0;
> +
> +	for (i = 0; i < ctrls->count; ++ctrl, ++i) {
> +		ret = uvc_ctrl_is_accessible(chain, ctrl->id,
> +					    ioctl == VIDIOC_G_EXT_CTRLS);
> +		if (ret)
> +			break;
> +	}
> +
> +	ctrls->error_idx = ioctl == VIDIOC_TRY_EXT_CTRLS ? i : ctrls->count;
> +
> +	return ret;
> +}
> +
>  static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh,
>  				 struct v4l2_ext_controls *ctrls)
>  {
> @@ -1000,6 +1020,10 @@ static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh,
>  	unsigned int i;
>  	int ret;
>  
> +	ret = uvc_ctrl_check_access(chain, ctrls, VIDIOC_G_EXT_CTRLS);
> +	if (ret < 0)
> +		return ret;
> +
>  	if (ctrls->which == V4L2_CTRL_WHICH_DEF_VAL) {
>  		for (i = 0; i < ctrls->count; ++ctrl, ++i) {
>  			struct v4l2_queryctrl qc = { .id = ctrl->id };
> @@ -1036,13 +1060,17 @@ static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh,
>  
>  static int uvc_ioctl_s_try_ext_ctrls(struct uvc_fh *handle,
>  				     struct v4l2_ext_controls *ctrls,
> -				     bool commit)
> +				     unsigned long ioctl)
>  {
>  	struct v4l2_ext_control *ctrl = ctrls->controls;
>  	struct uvc_video_chain *chain = handle->chain;
>  	unsigned int i;
>  	int ret;
>  
> +	ret = uvc_ctrl_check_access(chain, ctrls, ioctl);
> +	if (ret < 0)
> +		return ret;
> +
>  	ret = uvc_ctrl_begin(chain);
>  	if (ret < 0)
>  		return ret;
> @@ -1051,14 +1079,15 @@ static int uvc_ioctl_s_try_ext_ctrls(struct uvc_fh *handle,
>  		ret = uvc_ctrl_set(handle, ctrl);
>  		if (ret < 0) {
>  			uvc_ctrl_rollback(handle);
> -			ctrls->error_idx = commit ? ctrls->count : i;
> +			ctrls->error_idx = ioctl == VIDIOC_S_EXT_CTRLS ?
> +						    ctrls->count : i;
>  			return ret;
>  		}
>  	}
>  
>  	ctrls->error_idx = 0;
>  
> -	if (commit)
> +	if (ioctl == VIDIOC_S_EXT_CTRLS)
>  		return uvc_ctrl_commit(handle, ctrls->controls, ctrls->count);
>  	else
>  		return uvc_ctrl_rollback(handle);
> @@ -1069,7 +1098,7 @@ static int uvc_ioctl_s_ext_ctrls(struct file *file, void *fh,
>  {
>  	struct uvc_fh *handle = fh;
>  
> -	return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, true);
> +	return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, VIDIOC_S_EXT_CTRLS);
>  }
>  
>  static int uvc_ioctl_try_ext_ctrls(struct file *file, void *fh,
> @@ -1077,7 +1106,7 @@ static int uvc_ioctl_try_ext_ctrls(struct file *file, void *fh,
>  {
>  	struct uvc_fh *handle = fh;
>  
> -	return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, false);
> +	return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, VIDIOC_TRY_EXT_CTRLS);
>  }
>  
>  static int uvc_ioctl_querymenu(struct file *file, void *fh,
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index dc20021f7ee0..9471c342a310 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -902,6 +902,8 @@ static inline int uvc_ctrl_rollback(struct uvc_fh *handle)
>  
>  int uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl);
>  int uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl);
> +int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
> +			   bool read);
>  
>  int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
>  		      struct uvc_xu_control_query *xqry);

-- 
Regards,

Laurent Pinchart

  reply	other threads:[~2021-06-10 16:56 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-26  9:58 [PATCH v9 00/22] uvcvideo: Fix v4l2-compliance errors Ricardo Ribalda
2021-03-26  9:58 ` [PATCH v9 01/22] media: v4l2-ioctl: Fix check_ext_ctrls Ricardo Ribalda
2021-06-10 16:19   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 02/22] media: pvrusb2: Do not check for V4L2_CTRL_WHICH_DEF_VAL Ricardo Ribalda
2021-06-10 17:29   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 03/22] media: uvcvideo: " Ricardo Ribalda
2021-06-10 16:21   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 04/22] media: v4l2-ioctl: S_CTRL output the right value Ricardo Ribalda
2021-06-10 16:23   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 05/22] media: uvcvideo: Remove s_ctrl and g_ctrl Ricardo Ribalda
2021-06-10 16:24   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 06/22] media: uvcvideo: Set capability in s_param Ricardo Ribalda
2021-03-26  9:58 ` [PATCH v9 07/22] media: uvcvideo: Return -EIO for control errors Ricardo Ribalda
2021-03-26  9:58 ` [PATCH v9 08/22] media: uvcvideo: refactor __uvc_ctrl_add_mapping Ricardo Ribalda
2021-03-26  9:58 ` [PATCH v9 09/22] media: uvcvideo: Add support for V4L2_CTRL_TYPE_CTRL_CLASS Ricardo Ribalda
2021-06-10 16:42   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 10/22] media: uvcvideo: Use dev->name for querycap() Ricardo Ribalda
2021-06-10 16:44   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 11/22] media: uvcvideo: Set unique vdev name based in type Ricardo Ribalda
2021-06-10 16:45   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 12/22] media: uvcvideo: Increase the size of UVC_METADATA_BUF_SIZE Ricardo Ribalda
2021-06-10 16:48   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 13/22] media: uvcvideo: Use control names from framework Ricardo Ribalda
2021-06-10 16:50   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 14/22] media: uvcvideo: Check controls flags before accessing them Ricardo Ribalda
2021-06-10 16:55   ` Laurent Pinchart [this message]
2021-03-26  9:58 ` [PATCH v9 15/22] media: uvcvideo: Set error_idx during ctrl_commit errors Ricardo Ribalda
2021-06-10 17:05   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 16/22] media: uvcvideo: Return -EACCES to inactive controls Ricardo Ribalda
2021-03-27 11:23   ` Hans Verkuil
2021-06-10 17:28   ` Laurent Pinchart
2021-06-10 18:40     ` Ricardo Ribalda
2021-06-10 19:47       ` Ricardo Ribalda Delgado
2021-03-26  9:58 ` [PATCH v9 17/22] media: docs: Document the behaviour of uvcdriver Ricardo Ribalda
2021-03-27 11:19   ` Hans Verkuil
2021-03-27 12:01     ` Ricardo Ribalda
2021-03-27 12:03       ` Hans Verkuil
2021-06-10 17:08       ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 18/22] media: uvcvideo: Downgrade control error messages Ricardo Ribalda
2021-03-27 11:19   ` Hans Verkuil
2021-06-10 16:59   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 19/22] uvcvideo: uvc_ctrl_is_accessible: check for INACTIVE Ricardo Ribalda
2021-03-27 12:26   ` Ricardo Ribalda Delgado
2021-03-26  9:58 ` [PATCH v9 20/22] uvcvideo: improve error handling in uvc_query_ctrl() Ricardo Ribalda
2021-06-10 17:14   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 21/22] uvcvideo: don't spam the log in uvc_ctrl_restore_values() Ricardo Ribalda
2021-06-10 16:57   ` Laurent Pinchart
2021-03-26  9:58 ` [PATCH v9 22/22] uvc: use vb2 ioctl and fop helpers Ricardo Ribalda
2021-04-02  2:50   ` Tomasz Figa
2021-05-25  8:06 ` [PATCH v9 00/22] uvcvideo: Fix v4l2-compliance errors Tomasz Figa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YMJECjaaoqDWmnPL@pendragon.ideasonboard.com \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=hverkuil-cisco@xs4all.nl \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=ribalda@chromium.org \
    --cc=sergey.senozhatsky@gmail.com \
    --cc=tfiga@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.