Received: by 2002:a25:ef43:0:0:0:0:0 with SMTP id w3csp579032ybm; Fri, 29 May 2020 07:19:09 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw3zKBmvRlo0Gg/o90ow5yS7sQuF1W5Fya0ck4cMdXG8qm0n7iVXhM1fJiZmvr5Ndv8x+Ty X-Received: by 2002:a17:906:415a:: with SMTP id l26mr7641639ejk.291.1590761948791; Fri, 29 May 2020 07:19:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1590761948; cv=none; d=google.com; s=arc-20160816; b=jBTIoWdf6dHrGUzs04Qwc5yM6noWjX/KyRbvrStNKTXI3AlaFrXdwMmTZ/g1DEnv6L ZtP87iMDTpk+jbiG8dqiF7+MyyvVype+dRx0Hc535JZHptHe7gKJzhVPOcE2B+dEGVaw ojjdGM8JLahslj411L5BtOoTzNFgX+wljy8++48dIm+FNgVajBco8Ij3D90tGfTioG7F 6vola6lXMAVIX7wcWcy1ZM9skxhdPfokxSrLyG2G5mjQMH5trr1bvW+4rL/K5ELeGzqo szidh9pd/HaWeKhDgHWh4Q/7cjZqutAClVSxl26f6pIcOjhcBZ2ejq8LGyVlK0T8Bw6O xzSQ== 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:content-disposition :mime-version:references:message-id:subject:cc:to:from:date; bh=caxwk6GA9HkrTSIZEQRYQnuGGkS44Y9Q/uu3NR0+ATI=; b=ZfhOXEV15IBqzhSovHk7+duKoHQ8yOdJSy5ackIyRxxKzaX7FRIH0IaaO1otGMmXPK OX5Ll1UMLi4SOkluiiZVgNqf8oDJ3Xv6oSDbSV3LklN0l9GgKg55/qsm4XMjjxahUJE5 rEfSwsLgqboVIcfbiuMNTvxDKw4VBfQ/173lyeodS9UfmsvT6Az2M2viePF1VXLt4qaM KUVoXGjySMZ1GDEOOFnEuJfrJgZxBwyjC3CGpMbnzF9hhyS7aIorQo5S+4albhjkLVyX prJT1g56qFbsBGJxQvY+HKWnDaGUdTfKelmU0M+/UOTPJsuo8EM5DkhyXgrgpthNYJsG Oh1A== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d6si5508823edo.493.2020.05.29.07.18.45; Fri, 29 May 2020 07:19:08 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727112AbgE2OQL (ORCPT + 99 others); Fri, 29 May 2020 10:16:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38382 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726593AbgE2OQK (ORCPT ); Fri, 29 May 2020 10:16:10 -0400 Received: from ZenIV.linux.org.uk (zeniv.linux.org.uk [IPv6:2002:c35c:fd02::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 39932C03E969; Fri, 29 May 2020 07:16:09 -0700 (PDT) Received: from viro by ZenIV.linux.org.uk with local (Exim 4.93 #3 (Red Hat Linux)) id 1jefnf-00HZzJ-1U; Fri, 29 May 2020 14:15:55 +0000 Date: Fri, 29 May 2020 15:15:55 +0100 From: Al Viro To: Ian Abbott Cc: Linus Torvalds , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: Re: [PATCHES] uaccess comedi compat Message-ID: <20200529141555.GC23230@ZenIV.linux.org.uk> References: <20200528234025.GT23230@ZenIV.linux.org.uk> <20200529003419.GX23230@ZenIV.linux.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, May 29, 2020 at 11:48:51AM +0100, Ian Abbott wrote: > > Al Viro (10): > > comedi: move compat ioctl handling to native fops > > comedi: get rid of indirection via translated_ioctl() > > comedi: get rid of compat_alloc_user_space() mess in COMEDI_CHANINFO compat > > comedi: get rid of compat_alloc_user_space() mess in COMEDI_RANGEINFO compat > > comedi: get rid of compat_alloc_user_space() mess in COMEDI_INSN compat > > comedi: get rid of compat_alloc_user_space() mess in COMEDI_INSNLIST compat > > comedi: lift copy_from_user() into callers of __comedi_get_user_cmd() > > comedi: do_cmdtest_ioctl(): lift copyin/copyout into the caller > > comedi: do_cmd_ioctl(): lift copyin/copyout into the caller > > comedi: get rid of compat_alloc_user_space() mess in COMEDI_CMD{,TEST} compat > > There is a bug in patch 05. Patch 10 doesn't seem to have been sent yet (I > didn't receive it and I can't see it in the thread in the LKML archives). > I've signed off on 01-04, 06-09. #5 fixed, force-pushed to the same branch. As for s-o-b... are you sure that's the header you have in mind? Normally it's for the chain of transmission... Do you offer to take that series through comedi (or staging, or...) git tree? In that case s-o-b would make sense and I'd be happy to have it taken off my hands. Otherwise it probably should be Acked-by: or Reviewed-by: or Read-through-and-managed-not-to-throw-up: - up to you... > These should be Cc'd to Greg KH and to devel@driverdev.osuosl.org. FWIW, 10/10 seems to have been really lost; follows here: From 88833127a8f00da422ddef03425ad9b19eb65558 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 26 Apr 2020 09:27:23 -0400 Subject: [PATCH 10/10] comedi: get rid of compat_alloc_user_space() mess in COMEDI_CMD{,TEST} compat Signed-off-by: Al Viro --- drivers/staging/comedi/comedi_fops.c | 181 +++++++++++++---------------------- 1 file changed, 66 insertions(+), 115 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index f5ecfbfcdaf5..bcdb059e6bb6 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2930,155 +2930,106 @@ static int compat_rangeinfo(struct file *file, unsigned long arg) } /* Copy 32-bit cmd structure to native cmd structure. */ -static int get_compat_cmd(struct comedi_cmd __user *cmd, +static int get_compat_cmd(struct comedi_cmd *cmd, struct comedi32_cmd_struct __user *cmd32) { - int err; - union { - unsigned int uint; - compat_uptr_t uptr; - } temp; - - /* Copy cmd structure. */ - if (!access_ok(cmd32, sizeof(*cmd32)) || - !access_ok(cmd, sizeof(*cmd))) + struct comedi32_cmd_struct v32; + + if (copy_from_user(&v32, cmd32, sizeof(v32))) return -EFAULT; - err = 0; - err |= __get_user(temp.uint, &cmd32->subdev); - err |= __put_user(temp.uint, &cmd->subdev); - err |= __get_user(temp.uint, &cmd32->flags); - err |= __put_user(temp.uint, &cmd->flags); - err |= __get_user(temp.uint, &cmd32->start_src); - err |= __put_user(temp.uint, &cmd->start_src); - err |= __get_user(temp.uint, &cmd32->start_arg); - err |= __put_user(temp.uint, &cmd->start_arg); - err |= __get_user(temp.uint, &cmd32->scan_begin_src); - err |= __put_user(temp.uint, &cmd->scan_begin_src); - err |= __get_user(temp.uint, &cmd32->scan_begin_arg); - err |= __put_user(temp.uint, &cmd->scan_begin_arg); - err |= __get_user(temp.uint, &cmd32->convert_src); - err |= __put_user(temp.uint, &cmd->convert_src); - err |= __get_user(temp.uint, &cmd32->convert_arg); - err |= __put_user(temp.uint, &cmd->convert_arg); - err |= __get_user(temp.uint, &cmd32->scan_end_src); - err |= __put_user(temp.uint, &cmd->scan_end_src); - err |= __get_user(temp.uint, &cmd32->scan_end_arg); - err |= __put_user(temp.uint, &cmd->scan_end_arg); - err |= __get_user(temp.uint, &cmd32->stop_src); - err |= __put_user(temp.uint, &cmd->stop_src); - err |= __get_user(temp.uint, &cmd32->stop_arg); - err |= __put_user(temp.uint, &cmd->stop_arg); - err |= __get_user(temp.uptr, &cmd32->chanlist); - err |= __put_user((unsigned int __force *)compat_ptr(temp.uptr), - &cmd->chanlist); - err |= __get_user(temp.uint, &cmd32->chanlist_len); - err |= __put_user(temp.uint, &cmd->chanlist_len); - err |= __get_user(temp.uptr, &cmd32->data); - err |= __put_user(compat_ptr(temp.uptr), &cmd->data); - err |= __get_user(temp.uint, &cmd32->data_len); - err |= __put_user(temp.uint, &cmd->data_len); - return err ? -EFAULT : 0; + cmd->subdev = v32.subdev; + cmd->flags = v32.flags; + cmd->start_src = v32.start_src; + cmd->start_arg = v32.start_arg; + cmd->scan_begin_src = v32.scan_begin_src; + cmd->scan_begin_arg = v32.scan_begin_arg; + cmd->convert_src = v32.convert_src; + cmd->convert_arg = v32.convert_arg; + cmd->scan_end_src = v32.scan_end_src; + cmd->scan_end_arg = v32.scan_end_arg; + cmd->stop_src = v32.stop_src; + cmd->stop_arg = v32.stop_arg; + cmd->chanlist = compat_ptr(v32.chanlist); + cmd->chanlist_len = v32.chanlist_len; + cmd->data = compat_ptr(v32.data); + cmd->data_len = v32.data_len; + return 0; } /* Copy native cmd structure to 32-bit cmd structure. */ static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32, - struct comedi_cmd __user *cmd) -{ - int err; - unsigned int temp; - - /* - * Copy back most of cmd structure. - * - * Assume the pointer values are already valid. - * (Could use ptr_to_compat() to set them.) - */ - if (!access_ok(cmd, sizeof(*cmd)) || - !access_ok(cmd32, sizeof(*cmd32))) - return -EFAULT; - - err = 0; - err |= __get_user(temp, &cmd->subdev); - err |= __put_user(temp, &cmd32->subdev); - err |= __get_user(temp, &cmd->flags); - err |= __put_user(temp, &cmd32->flags); - err |= __get_user(temp, &cmd->start_src); - err |= __put_user(temp, &cmd32->start_src); - err |= __get_user(temp, &cmd->start_arg); - err |= __put_user(temp, &cmd32->start_arg); - err |= __get_user(temp, &cmd->scan_begin_src); - err |= __put_user(temp, &cmd32->scan_begin_src); - err |= __get_user(temp, &cmd->scan_begin_arg); - err |= __put_user(temp, &cmd32->scan_begin_arg); - err |= __get_user(temp, &cmd->convert_src); - err |= __put_user(temp, &cmd32->convert_src); - err |= __get_user(temp, &cmd->convert_arg); - err |= __put_user(temp, &cmd32->convert_arg); - err |= __get_user(temp, &cmd->scan_end_src); - err |= __put_user(temp, &cmd32->scan_end_src); - err |= __get_user(temp, &cmd->scan_end_arg); - err |= __put_user(temp, &cmd32->scan_end_arg); - err |= __get_user(temp, &cmd->stop_src); - err |= __put_user(temp, &cmd32->stop_src); - err |= __get_user(temp, &cmd->stop_arg); - err |= __put_user(temp, &cmd32->stop_arg); + struct comedi_cmd *cmd) +{ + struct comedi32_cmd_struct v32; + + memset(&v32, 0, sizeof(v32)); + v32.subdev = cmd->subdev; + v32.flags = cmd->flags; + v32.start_src = cmd->start_src; + v32.start_arg = cmd->start_arg; + v32.scan_begin_src = cmd->scan_begin_src; + v32.scan_begin_arg = cmd->scan_begin_arg; + v32.convert_src = cmd->convert_src; + v32.convert_arg = cmd->convert_arg; + v32.scan_end_src = cmd->scan_end_src; + v32.scan_end_arg = cmd->scan_end_arg; + v32.stop_src = cmd->stop_src; + v32.stop_arg = cmd->stop_arg; /* Assume chanlist pointer is unchanged. */ - err |= __get_user(temp, &cmd->chanlist_len); - err |= __put_user(temp, &cmd32->chanlist_len); - /* Assume data pointer is unchanged. */ - err |= __get_user(temp, &cmd->data_len); - err |= __put_user(temp, &cmd32->data_len); - return err ? -EFAULT : 0; + v32.chanlist = ptr_to_compat(cmd->chanlist); + v32.chanlist_len = cmd->chanlist_len; + v32.data = ptr_to_compat(cmd->data); + v32.data_len = cmd->data_len; + return copy_to_user(cmd32, &v32, sizeof(v32)); } /* Handle 32-bit COMEDI_CMD ioctl. */ static int compat_cmd(struct file *file, unsigned long arg) { - struct comedi_cmd __user *cmd; - struct comedi32_cmd_struct __user *cmd32; + struct comedi_file *cfp = file->private_data; + struct comedi_device *dev = cfp->dev; + struct comedi_cmd cmd; + bool copy = false; int rc, err; - cmd32 = compat_ptr(arg); - cmd = compat_alloc_user_space(sizeof(*cmd)); - - rc = get_compat_cmd(cmd, cmd32); + rc = get_compat_cmd(&cmd, compat_ptr(arg)); if (rc) return rc; - rc = comedi_unlocked_ioctl(file, COMEDI_CMD, (unsigned long)cmd); - if (rc == -EAGAIN) { + mutex_lock(&dev->mutex); + rc = do_cmd_ioctl(dev, &cmd, ©, file); + mutex_unlock(&dev->mutex); + if (copy) { /* Special case: copy cmd back to user. */ - err = put_compat_cmd(cmd32, cmd); + err = put_compat_cmd(compat_ptr(arg), &cmd); if (err) rc = err; } - return rc; } /* Handle 32-bit COMEDI_CMDTEST ioctl. */ static int compat_cmdtest(struct file *file, unsigned long arg) { - struct comedi_cmd __user *cmd; - struct comedi32_cmd_struct __user *cmd32; + struct comedi_file *cfp = file->private_data; + struct comedi_device *dev = cfp->dev; + struct comedi_cmd cmd; + bool copy = false; int rc, err; - cmd32 = compat_ptr(arg); - cmd = compat_alloc_user_space(sizeof(*cmd)); - - rc = get_compat_cmd(cmd, cmd32); + rc = get_compat_cmd(&cmd, compat_ptr(arg)); if (rc) return rc; - rc = comedi_unlocked_ioctl(file, COMEDI_CMDTEST, (unsigned long)cmd); - if (rc < 0) - return rc; - - err = put_compat_cmd(cmd32, cmd); - if (err) - rc = err; - + mutex_lock(&dev->mutex); + rc = do_cmdtest_ioctl(dev, &cmd, ©, file); + mutex_unlock(&dev->mutex); + if (copy) { + err = put_compat_cmd(compat_ptr(arg), &cmd); + if (err) + rc = err; + } return rc; } -- 2.11.0