Received: by 10.223.185.116 with SMTP id b49csp6431802wrg; Wed, 28 Feb 2018 09:17:17 -0800 (PST) X-Google-Smtp-Source: AG47ELsJGOrp8ZeHrfV62pUNHI09m2h0nJkquxJ8w7GsvglCl5VKs8gGq388vK/rRiTyhQHMOYld X-Received: by 2002:a17:902:e85:: with SMTP id 5-v6mr6091732plx.420.1519838237217; Wed, 28 Feb 2018 09:17:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519838237; cv=none; d=google.com; s=arc-20160816; b=tfyETMLFQFk/LEF49db9DjDxjGGs+SD0EV9QaxC3vcZ+c+TAA6qXyXP27zUPmuvKPo sKLeTZnr06KDm+vpuG8aFV9fI7qRiE7UQ1xh0VAa2GNjnr3mgkuGso9HiATDZJvTJoKP EZ71MHU/kmH6sJg7vc/oD+UmClSrtN6tAz2d1umHEIr55g7t5XVD4kfJlw43JquEuP2e UaJEqwVgUA2T1DXUQ1CP8ZzMQqiV+lWyPJrdoy16IpIlcVwaJDMFgASltI8KFY3120q/ jY9xXBUNzDTNXnIQodWxg+n1dHKCe9J16Skl0zTzPkFdiN/kZ4nGkGrtziLTvikMG7Ng 9fSw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition :arc-authentication-results; bh=gJAjHStlmJ/VBYIyDs/oiIHohxRyZwKTNPxt5Bk9wgg=; b=RConO5xQ5ttzICKBQLeoYauzh8yuFnYOvU3iwYC410wvslPfNwtSehosJ/dl7/UMe1 0r9ZTTJt5Seu3cMr+NUVo8Lv35hb3mNC1JDvybT3M/8wSt6qe7z7GfmR0JTGL/7UfrIp +OgKWyyC7lCP7XMy8lOlJGQJfbOAxcPGPHAU+Wtc3BJXOKm0Nj/v7BgvhaaMP+ZrKXPB ll3togWwTUGcT1zHPfhgA8LxtPS7o/WbkI6tPHhfYUwrfATLtUF7tWQ/xKz9ENBwJlIU NYqvSxSpPQ4LitZNoWEIjOMcNASl3XjIAe+vCA8XjTr3g/foofGyI64eovDQ2wrVr3nc 48RQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t14si1489679pfa.162.2018.02.28.09.17.01; Wed, 28 Feb 2018 09:17:17 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933569AbeB1Psd (ORCPT + 99 others); Wed, 28 Feb 2018 10:48:33 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:34259 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933174AbeB1Psb (ORCPT ); Wed, 28 Feb 2018 10:48:31 -0500 Received: from [2a02:8011:400e:2:6f00:88c8:c921:d332] (helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1er3Ym-0006Xh-59; Wed, 28 Feb 2018 15:22:24 +0000 Received: from ben by deadeye with local (Exim 4.90_1) (envelope-from ) id 1er3Yl-0000Js-2W; Wed, 28 Feb 2018 15:22:23 +0000 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Mauro Carvalho Chehab" , "Sakari Ailus" , "Hans Verkuil" Date: Wed, 28 Feb 2018 15:20:18 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 247/254] media: v4l2-compat-ioctl32.c: fix ctrl_is_pointer In-Reply-To: X-SA-Exim-Connect-IP: 2a02:8011:400e:2:6f00:88c8:c921:d332 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.55-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Hans Verkuil commit b8c601e8af2d08f733d74defa8465303391bb930 upstream. ctrl_is_pointer just hardcoded two known string controls, but that caused problems when using e.g. custom controls that use a pointer for the payload. Reimplement this function: it now finds the v4l2_ctrl (if the driver uses the control framework) or it calls vidioc_query_ext_ctrl (if the driver implements that directly). In both cases it can now check if the control is a pointer control or not. Signed-off-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab [bwh: Rebased on top of some earlier fixes] Signed-off-by: Ben Hutchings --- --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -571,24 +573,32 @@ struct v4l2_ext_control32 { }; } __attribute__ ((packed)); -/* The following function really belong in v4l2-common, but that causes - a circular dependency between modules. We need to think about this, but - for now this will do. */ - -/* Return non-zero if this control is a pointer type. Currently only - type STRING is a pointer type. */ -static inline int ctrl_is_pointer(u32 id) -{ - switch (id) { - case V4L2_CID_RDS_TX_PS_NAME: - case V4L2_CID_RDS_TX_RADIO_TEXT: - return 1; - default: - return 0; +/* Return true if this control is a pointer type. */ +static inline bool ctrl_is_pointer(struct file *file, u32 id) +{ + struct video_device *vdev = video_devdata(file); + struct v4l2_fh *fh = NULL; + struct v4l2_ctrl_handler *hdl = NULL; + + if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags)) + fh = file->private_data; + + if (fh && fh->ctrl_handler) + hdl = fh->ctrl_handler; + else if (vdev->ctrl_handler) + hdl = vdev->ctrl_handler; + + if (hdl) { + struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, id); + + return ctrl && ctrl->type == V4L2_CTRL_TYPE_STRING; } + return false; } -static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up) +static int get_v4l2_ext_controls32(struct file *file, + struct v4l2_ext_controls *kp, + struct v4l2_ext_controls32 __user *up) { struct v4l2_ext_control32 __user *ucontrols; struct v4l2_ext_control __user *kcontrols; @@ -620,7 +630,7 @@ static int get_v4l2_ext_controls32(struc return -EFAULT; if (get_user(id, &kcontrols->id)) return -EFAULT; - if (ctrl_is_pointer(id)) { + if (ctrl_is_pointer(file, id)) { void __user *s; if (get_user(p, &ucontrols->string)) @@ -635,7 +645,9 @@ static int get_v4l2_ext_controls32(struc return 0; } -static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up) +static int put_v4l2_ext_controls32(struct file *file, + struct v4l2_ext_controls *kp, + struct v4l2_ext_controls32 __user *up) { struct v4l2_ext_control32 __user *ucontrols; struct v4l2_ext_control __user *kcontrols = @@ -667,7 +679,7 @@ static int put_v4l2_ext_controls32(struc /* Do not modify the pointer when copying a pointer control. The contents of the pointer was changed, not the pointer itself. */ - if (ctrl_is_pointer(id)) + if (ctrl_is_pointer(file, id)) size -= sizeof(ucontrols->value64); if (copy_in_user(ucontrols, kcontrols, size)) return -EFAULT; @@ -881,7 +893,7 @@ static long do_video_ioctl(struct file * case VIDIOC_G_EXT_CTRLS: case VIDIOC_S_EXT_CTRLS: case VIDIOC_TRY_EXT_CTRLS: - err = get_v4l2_ext_controls32(&karg.v2ecs, up); + err = get_v4l2_ext_controls32(file, &karg.v2ecs, up); compatible_arg = 0; break; case VIDIOC_DQEVENT: @@ -908,7 +920,7 @@ static long do_video_ioctl(struct file * case VIDIOC_G_EXT_CTRLS: case VIDIOC_S_EXT_CTRLS: case VIDIOC_TRY_EXT_CTRLS: - if (put_v4l2_ext_controls32(&karg.v2ecs, up)) + if (put_v4l2_ext_controls32(file, &karg.v2ecs, up)) err = -EFAULT; break; }