Received: by 2002:a05:6a10:eb17:0:0:0:0 with SMTP id hx23csp609169pxb; Thu, 9 Sep 2021 08:08:12 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyhG13BdDc9eSwXx/ztmmutY2g1cW8Rd82Ca2k9oqAnfXrywzwpm9gNgyLC2IX6jzXlzICb X-Received: by 2002:a2e:bb85:: with SMTP id y5mr249636lje.207.1631200092381; Thu, 09 Sep 2021 08:08:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631200092; cv=none; d=google.com; s=arc-20160816; b=z0774vGHKiqVYFrQ/mG1HT9qZO7Qmu4KsC4ZsCz4ZlchBiENTW6Z+P5VsHM+ObDANX f8a0PQLjqAYw0ZY6HNet7MtoPsFCfUqWtdF+zC+FGNnLnU19cNSPN3pxxYiz8y23Hd2l Rlgrw5wQvGW5XORBAuoK7IXi3rT61IYJK4pT8UfRYT7J5qpvuHqP/oWrI9zth7RSE909 N/N+fINK7uArxnTL+3emj/oWuiDvFTFlTh59cNApL8Vt/8H5MDoS/Okvi3aw0SR+AwOB 2t6frXCQ9ZqbYJWFP8sDys2otw/krkvE+PtsghjS0sowFkmBA15ze8vGHddfIabYlGze D7sg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=2/YVdOGpA7p9VVsleNcFecmocu6P9r8RpItIOBc2sY0=; b=ZY+ZhpeXYvS4Bl4pj33Yd3fv045BneEaPC571tZzfQ1EjT4SzvG8QCtns73Jm24gWQ 1gMh8kjKGzDRilgczU4yE3JG6wbp98J5z27QGodWmqwUrL85wSUnXS5CG7G9fAwKrvli 7ZkxS4QmkqkqdrWSJLb3UDs/fUGIAv7UdQ2ppRaiU4jJiCOmDdRxhlU8leSRQRBHyObu CWKkK5/qlMRK1MWdgCUrUE0rdL2HCCu9udmJKMt/yMNS+x985WHhUQNAv7LrGc1kfgVs Fo7R/a8BrWCY93ogu4a/F3LJVSGR/qCR7T1EI9uCyX5J1Jod34c+bFs3UdTEOiuGys0O 7odw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=YlnW+Tf8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ze16si2073552ejb.96.2021.09.09.08.07.36; Thu, 09 Sep 2021 08:08:12 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=YlnW+Tf8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237100AbhIIPEq (ORCPT + 99 others); Thu, 9 Sep 2021 11:04:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51864 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239117AbhIIPCH (ORCPT ); Thu, 9 Sep 2021 11:02:07 -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 C974BC0613F0 for ; Thu, 9 Sep 2021 08:00:51 -0700 (PDT) Received: by mail-ed1-x535.google.com with SMTP id i6so3088356edu.1 for ; Thu, 09 Sep 2021 08:00:51 -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=2/YVdOGpA7p9VVsleNcFecmocu6P9r8RpItIOBc2sY0=; b=YlnW+Tf82GzMUYEZ5yXPtk6LJVaLm17//C+nq0HjUgu5F8UDQPNqwxLMnM16+ackxX 70XwEOLqJ+GzlQ04FpROOPEnMLAfc3OgjtZY8pxF2w/3zdVuwdlGO3KnIpb7FYMMQKRE 5kHUVvl8IOYkg5oTyEQsHFPf9+9qOlLjI2sOk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2/YVdOGpA7p9VVsleNcFecmocu6P9r8RpItIOBc2sY0=; b=gIUdyQSDBkMeuo9n2MqrgICGRORXz9wAeZkz1al1N974qxElElb+KLd0nLy5nPPcqD J5ez1dIdpR81OFPCeBj98SukMNmLqk5kT6i8kp4aaKghX/kKeXqo1XJHGu+27e+3ismY pdwt/FX9IS3ktvr/sCkfY9gejREEeEcxjYhbWoTmEhM5aUaWkIrS+auWWzsNoUCbB5LD lcPrGI+QJiULKYAcHZgJl2ZsUP4IcCT79wBRRIztyPFSL9CYL8kirsQilu3dFBrrya/a 0kBwhGfoJIPuFFuW2YPh7ahvfHq50oHjenrhJmAIrC8RTMvfFnmJjNNZn2MV4qlKLn/d rgyQ== X-Gm-Message-State: AOAM533O1K6dSkeu6cxI9RWbJsXtk+RkV4TimmdgUJIMaPco9AaqYbmq orFSFqNA7d7R0Nq/oorOONZ7og== X-Received: by 2002:aa7:df09:: with SMTP id c9mr3736664edy.243.1631199650286; Thu, 09 Sep 2021 08:00:50 -0700 (PDT) Received: from alco.lan (80.71.134.83.ipv4.parknet.dk. [80.71.134.83]) by smtp.gmail.com with ESMTPSA id h8sm1139644ejj.22.2021.09.09.08.00.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 08:00:50 -0700 (PDT) From: Ricardo Ribalda To: Laurent Pinchart , Hans Verkuil , Mauro Carvalho Chehab , Sergey Senozhatsky , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, tfiga@chromium.org Cc: Hans Verkuil , Ricardo Ribalda , Hans Verkuil Subject: [PATCH 1/4] media: uvcvideo: uvc_ctrl_is_accessible: check for INACTIVE Date: Thu, 9 Sep 2021 17:00:43 +0200 Message-Id: <20210909150046.57615-2-ribalda@chromium.org> X-Mailer: git-send-email 2.33.0.153.gba50c8fa24-goog In-Reply-To: <20210909150046.57615-1-ribalda@chromium.org> References: <20210909150046.57615-1-ribalda@chromium.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 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, which returns an invalid errorcode. This fixes: warn: v4l2-test-controls.cpp(483): s_ctrl returned EIO   warn: v4l2-test-controls.cpp(483): s_ctrl returned EIO test VIDIOC_G/S_CTRL: OK   warn: v4l2-test-controls.cpp(739): s_ext_ctrls returned EIO   warn: v4l2-test-controls.cpp(739): s_ext_ctrls returned EIO   warn: v4l2-test-controls.cpp(816): s_ext_ctrls returned EIO test VIDIOC_G/S/TRY_EXT_CTRLS: OK Tested with: v4l2-ctl -c auto_exposure=1 OK v4l2-ctl -c exposure_time_absolute=251 OK v4l2-ctl -c auto_exposure=3 OK v4l2-ctl -c exposure_time_absolute=251 VIDIOC_S_EXT_CTRLS: failed: Input/output error exposure_time_absolute: Input/output error ERROR v4l2-ctl -c auto_exposure=3,exposure_time_absolute=251,auto_exposure=1 v4l2-ctl -C auto_exposure,exposure_time_absolute   auto_exposure: 1 exposure_time_absolute: 251 Reviewed-by: Ricardo Ribalda Signed-off-by: Hans Verkuil --- drivers/media/usb/uvc/uvc_ctrl.c | 47 +++++++++++++++++++++++++++++++- drivers/media/usb/uvc/uvc_v4l2.c | 4 +-- drivers/media/usb/uvc/uvcvideo.h | 3 +- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 30bfe9069a1f..5f6aca7336d9 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1042,11 +1042,33 @@ static int uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id, return 0; } +/** + * uvc_ctrl_is_accessible() - Check if a control can be read/writen/tried. + * @chain: uvc_video_chain that the controls belong to. + * @v4l2_id: video4linux id of the control. + * @ctrl: Other controls that will be accessed in the ioctl. + * @ioctl: ioctl used to access the control. + * + * Check if a control can be accessed by a specicific ioctl operation, + * assuming that other controls are also going to be accessed by that ioctl. + * We need to check the value of the other controls, to support operations + * where a master value is changed with a slave value. Eg. + * auto_exposure=1,exposure_time_absolute=251 + * + */ 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; @@ -1061,6 +1083,29 @@ 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; + + /* + * Iterate backwards in cases where the master control is accessed + * multiple times in the same ioctl. We want the last value. + */ + 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 7a565a7371d2..ad0f422d6999 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -816,8 +816,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 e872e9a96faf..a087d66d2105 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -868,7 +868,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.33.0.153.gba50c8fa24-goog