From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 21560C433E3 for ; Fri, 26 Mar 2021 10:00:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0690A601FB for ; Fri, 26 Mar 2021 10:00:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230458AbhCZKAK (ORCPT ); Fri, 26 Mar 2021 06:00:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230137AbhCZJ67 (ORCPT ); Fri, 26 Mar 2021 05:58:59 -0400 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 39ECEC0613AA for ; Fri, 26 Mar 2021 02:58:59 -0700 (PDT) Received: by mail-ed1-x535.google.com with SMTP id j3so5580237edp.11 for ; Fri, 26 Mar 2021 02:58:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=uCrEyotbYF7tjluvQkWSRucWwy5lZOwnlMYsosdr5+s=; b=KRXW799zU2MTkSiZwFPeS/NQnIfH+m9lYWRHp/dmwKY+tmOr2yVorJWeFyRXrK65Te CnldOEnO1NNXxfPRFjj0aGq/W9BnGpxTlaLBd2HPBlLowAt8bGqEVbHG6LfWKeMQeVhY 3ZJSd/EDfxdk7heSx/BtvGbxpys+b3clSZVGg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=uCrEyotbYF7tjluvQkWSRucWwy5lZOwnlMYsosdr5+s=; b=Jdlbt4vpVOsCfL1Ca+hodZCcSLWkLWG0Gl7BdYYnuYtH1sdzp5hGD79r6CIvn5dAfX DCPfP2j9nGH/vodr7QZ3owl7KAEJRFcvYTUShlioag4VjwoXjgmUw8hGDeyphcMYtERx Sa33DP1BTumYjOQGj4EC2MOEKnxgY04yCOU5pktsROp5Y5hNEPGF2tm0SYbiBpopMITY /gasPKjDI+cKceYqD2UaNvDLs+m30bPp9rDupxRSlD9qHxvNQqfc9NHKBN/grhtNX8Qu 6qPXV0lnDUaD7VzGgukSCHKWDlh3suVIakFGZTAtkCG037knwy0xXsDifhnGghO7wCRC TloA== X-Gm-Message-State: AOAM533021/VAsU8FgekTXwYpeWA2DkyzVlpFQB5R+lq+6h+YZyFmo8J FNgYUgLwlubcLXktUESWcHQhdA== X-Google-Smtp-Source: ABdhPJwGZlffD5wb8dSneMODwCyR7usaPrHR/9r/bzx2a8jFZm4TQieAiVLvCyG4R0aFXP7Gv9tfsA== X-Received: by 2002:aa7:d74b:: with SMTP id a11mr13885736eds.92.1616752738024; Fri, 26 Mar 2021 02:58:58 -0700 (PDT) Received: from alco.lan ([80.71.134.83]) by smtp.gmail.com with ESMTPSA id h13sm4036658edz.71.2021.03.26.02.58.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Mar 2021 02:58:57 -0700 (PDT) From: Ricardo Ribalda To: Laurent Pinchart , Mauro Carvalho Chehab , Hans Verkuil , Sergey Senozhatsky , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, tfiga@chromium.org Cc: Hans Verkuil , Hans Verkuil Subject: [PATCH v9 19/22] uvcvideo: uvc_ctrl_is_accessible: check for INACTIVE Date: Fri, 26 Mar 2021 10:58:37 +0100 Message-Id: <20210326095840.364424-20-ribalda@chromium.org> X-Mailer: git-send-email 2.31.0.291.g576ba9dcdaf-goog In-Reply-To: <20210326095840.364424-1-ribalda@chromium.org> References: <20210326095840.364424-1-ribalda@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Hans Verkuil Check for inactive controls in uvc_ctrl_is_accessible(). Use the new value for the master_id controls if present, otherwise use the existing value to determine if it is OK to set the control. Doing this here avoids attempting to set an inactive control, which will return an error from the USB device. Signed-off-by: Hans Verkuil --- drivers/media/usb/uvc/uvc_ctrl.c | 28 +++++++++++++++++++++++++++- drivers/media/usb/uvc/uvc_v4l2.c | 4 ++-- drivers/media/usb/uvc/uvcvideo.h | 3 ++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index d9d4add1e813..6e7b904bc33d 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1047,10 +1047,18 @@ static int uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id, } int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id, - bool read) + const struct v4l2_ext_controls *ctrls, + unsigned long ioctl) { + struct uvc_control_mapping *master_map = NULL; + struct uvc_control *master_ctrl = NULL; struct uvc_control_mapping *mapping; struct uvc_control *ctrl; + bool read = ioctl == VIDIOC_G_EXT_CTRLS; + bool try = ioctl == VIDIOC_TRY_EXT_CTRLS; + s32 val; + int ret; + int i; if (__uvc_query_v4l2_class(chain, v4l2_id, 0) >= 0) return -EACCES; @@ -1065,6 +1073,24 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id, if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) && !read) return -EACCES; + if (read || try || !mapping->master_id) + return 0; + + for (i = ctrls->count - 1; i >= 0; i--) + if (ctrls->controls[i].id == mapping->master_id) + return ctrls->controls[i].value == + mapping->master_manual ? 0 : -EACCES; + + __uvc_find_control(ctrl->entity, mapping->master_id, &master_map, + &master_ctrl, 0); + + if (!master_ctrl || !(master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) + return 0; + + ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val); + if (ret >= 0 && val != mapping->master_manual) + return -EACCES; + return 0; } diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 8d8b12a4db34..0f4d893eff46 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -1000,8 +1000,8 @@ static int uvc_ctrl_check_access(struct uvc_video_chain *chain, int ret = 0; for (i = 0; i < ctrls->count; ++ctrl, ++i) { - ret = uvc_ctrl_is_accessible(chain, ctrl->id, - ioctl == VIDIOC_G_EXT_CTRLS); + ret = uvc_ctrl_is_accessible(chain, ctrl->id, ctrls, + ioctl); if (ret) break; } diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 0313b30f0cea..20bc681315fb 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -901,7 +901,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); + const struct v4l2_ext_controls *ctrls, + unsigned long ioctl); int uvc_xu_ctrl_query(struct uvc_video_chain *chain, struct uvc_xu_control_query *xqry); -- 2.31.0.291.g576ba9dcdaf-goog