From patchwork Tue Jul 30 19:25:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 170092 Delivered-To: patch@linaro.org Received: by 2002:ac9:2daa:0:0:0:0:0 with SMTP id g42csp5042522oce; Tue, 30 Jul 2019 12:30:10 -0700 (PDT) X-Google-Smtp-Source: APXvYqyruRq1NmyJOpY6hW+t5T8mNY9VltrZb2vaWqLpMfY8xRFGpTM6mI/v45ZT0hNbR0zjrt2d X-Received: by 2002:a62:be0c:: with SMTP id l12mr43725258pff.224.1564515010768; Tue, 30 Jul 2019 12:30:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1564515010; cv=none; d=google.com; s=arc-20160816; b=tfli3rics4C/8TmFtDcxC2RfAKmz0W5itxDi/NCEypWa5ZGXqXDqIJkRgUN56o2hP0 8HsoR3En4P5sRABzpSe8ivMUKk5lIb7FdV1pJqSLZNTAxcgeAGhyxF6+69XzyEhFMedM ROA3OFf3qdsFY8s76JUvIcAWYfRP3seCRnKSXUrkD+fuatkhaZyc7FzWPQXdk8v4voEg osk/58PzmSYuvE6gm+lVYcZPQRJkZCrtiNGIb8FOLMz1TnaUaM2z4SOW7FhAko6W2Qdr 2A6ojK5iPWzWpUIUZ6sGb/WufNcKsHN/9+bYbJZxudkhLALAkRdtBqZasN3pSaUDMKyW vgTA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=smF3mt0BG5r+MHsyjxDeX9w8LmhgFGLhd5gLfU/jX3Y=; b=Np0XyIPO1SNR3QajJkL61n6x8RF0oOQ0XID9yZb6gE6NnGlMo2i+A9JGh19mRF9x3D ayXgX9Nltv0J5kMO8Ymgmf8wCjWD4RmBKL30u4N16xswJdrwt3hzBcB0tSp8HApMOVwj 15Waa9NGTz5O0/dl1DCqSJ5TqXHxV3x+t+71hcKmNZbwYdeO1VDx5splImO+j9M4Dm6s tzmjLXa0ubFN2DRHx1NIxST7MSm4cIihvvxu0vBV3zJBN8iBFjVQxFkQngCYBHGsIWXa 5WCI27dUDuOtZ/2HHvWun/cyIs+HTDTgDpjYiNocTOwEqXVQKgKfxFFl+fCZwj76U3Yf O8uQ== 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 24si32969823pgu.501.2019.07.30.12.30.10; Tue, 30 Jul 2019 12:30:10 -0700 (PDT) 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 S1729423AbfG3TaJ (ORCPT + 29 others); Tue, 30 Jul 2019 15:30:09 -0400 Received: from mout.kundenserver.de ([212.227.126.131]:37817 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728677AbfG3TaI (ORCPT ); Tue, 30 Jul 2019 15:30:08 -0400 Received: from threadripper.lan ([149.172.19.189]) by mrelayeu.kundenserver.de (mreue010 [212.227.15.129]) with ESMTPA (Nemesis) id 1Mvs2R-1iC0D41RtH-00su5I; Tue, 30 Jul 2019 21:29:49 +0200 From: Arnd Bergmann To: Alexander Viro Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Arnd Bergmann , Amir Goldstein , Dave Chinner , "Darrick J. Wong" , Jan Kara , David Howells , Jens Axboe , Matthew Wilcox , Phillip Potter Subject: [PATCH v5 10/29] compat_ioctl: add compat_ptr_ioctl() Date: Tue, 30 Jul 2019 21:25:21 +0200 Message-Id: <20190730192552.4014288-11-arnd@arndb.de> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20190730192552.4014288-1-arnd@arndb.de> References: <20190730192552.4014288-1-arnd@arndb.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:oaGT+dgCZ7eW61FvI0TZ9DdaBUodVzKQE6fy+DvsydsjtaA9t5t YNnIgO4VmLAEqquIOxEvpgquoRzqJpizCxZLxmHRWNeM82CA74cvT8w4AqLlGT2jwBI2T41 9zXvcLKmuHlP0UV9NQfQRrVJ7XM9SRVtuvqO8+DHZpMZJB36p/mrh7jnkrETr//v+3RYnxW bcsdG1mf3FtsarekW2Dsw== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1; V03:K0:3P75hwXu32Y=:yg4yB85JnCIIeA3T5b7w+z 6edHtMRI89PheXd23dSpuey5gLS/R1d2ABuxzHKIwHjEhrFYDahUTXurS8tMXtubp9Y+EMfDa O/WyXfyNDKIqf+1SyfAkVR8qJpOg260mRzQBVSNoPb0pTO5f2rmRltb+tVDR0IRgtD0Hw7OwM 4THx1WA1mjP9gXRp1yTZ2agisqmmhMYrXZtpewerRiL3kPC75uSBfLxhhTz31JNtVVBsfENQn 7sO2iYl0U28Uw8YQkGSRw3sL+3YjRlQeE7tHjW+fg0vzVfSnBGWlcXgfGGqL0vn8MzJTd3c+x l18NehHDl1xDZE3+eOLtPwyEsFh7cGk/pa/kiK2DzsoasnRo3hT9pEf00MyfVBmXVroK+UHzQ phV2wnJdmv+VaCew4+UB3umKmMbcZtVy989/CFjTXeYT+f8aAbQLPA+rRm9YpeXd211906qvS rNkFoRMRsZWqMGiT5I4+R8/30DHI+W9683aWBb95oXm0iVkBv0O3NqhMiPUaanDOnKhshNiWj LflYrLMjDaVuVCUOOqXd/hRL5g5op6Q/nAUbLYwZix7XTce480XJZlCuhAwTRpR/RIkjtWOee TN2PQ1PYgH7mm53aF6Fk+ske/686btFFgeJhPKueLW7L4vse0dey3vesME7UrbK7yy6ArTSjC gOj3z4V1pI1J6Pho3O8VSXxSOKI82ota2xMpDjOr4Y4SmEmkZ445sUuQEv/gdQrrvYSxTz9zz sNiXQB23GT/IK2Y1LyUUyZHHE1gCwquDBjZFkw== Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Many drivers have ioctl() handlers that are completely compatible between 32-bit and 64-bit architectures, except for the argument that is passed down from user space and may have to be passed through compat_ptr() in order to become a valid 64-bit pointer. Using ".compat_ptr = compat_ptr_ioctl" in file operations should let us simplify a lot of those drivers to avoid #ifdef checks, and convert additional drivers that don't have proper compat handling yet. On most architectures, the compat_ptr_ioctl() just passes all arguments to the corresponding ->ioctl handler. The exception is arch/s390, where compat_ptr() clears the top bit of a 32-bit pointer value, so user space pointers to the second 2GB alias the first 2GB, as is the case for native 32-bit s390 user space. The compat_ptr_ioctl() function must therefore be used only with ioctl functions that either ignore the argument or pass a pointer to a compatible data type. If any ioctl command handled by fops->unlocked_ioctl passes a plain integer instead of a pointer, or any of the passed data types is incompatible between 32-bit and 64-bit architectures, a proper handler is required instead of compat_ptr_ioctl. Signed-off-by: Arnd Bergmann --- v3: add a better description v2: use compat_ptr_ioctl instead of generic_compat_ioctl_ptrarg, as suggested by Al Viro --- fs/ioctl.c | 35 +++++++++++++++++++++++++++++++++++ include/linux/fs.h | 7 +++++++ 2 files changed, 42 insertions(+) -- 2.20.0 diff --git a/fs/ioctl.c b/fs/ioctl.c index 9d26251f34a9..812061ba667a 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -748,3 +749,37 @@ SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) { return ksys_ioctl(fd, cmd, arg); } + +#ifdef CONFIG_COMPAT +/** + * compat_ptr_ioctl - generic implementation of .compat_ioctl file operation + * + * This is not normally called as a function, but instead set in struct + * file_operations as + * + * .compat_ioctl = compat_ptr_ioctl, + * + * On most architectures, the compat_ptr_ioctl() just passes all arguments + * to the corresponding ->ioctl handler. The exception is arch/s390, where + * compat_ptr() clears the top bit of a 32-bit pointer value, so user space + * pointers to the second 2GB alias the first 2GB, as is the case for + * native 32-bit s390 user space. + * + * The compat_ptr_ioctl() function must therefore be used only with ioctl + * functions that either ignore the argument or pass a pointer to a + * compatible data type. + * + * If any ioctl command handled by fops->unlocked_ioctl passes a plain + * integer instead of a pointer, or any of the passed data types + * is incompatible between 32-bit and 64-bit architectures, a proper + * handler is required instead of compat_ptr_ioctl. + */ +long compat_ptr_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + if (!file->f_op->unlocked_ioctl) + return -ENOIOCTLCMD; + + return file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); +} +EXPORT_SYMBOL(compat_ptr_ioctl); +#endif diff --git a/include/linux/fs.h b/include/linux/fs.h index 56b8e358af5c..07b032e58032 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1702,6 +1702,13 @@ int vfs_mkobj(struct dentry *, umode_t, extern long vfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_COMPAT +extern long compat_ptr_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); +#else +#define compat_ptr_ioctl NULL +#endif + /* * VFS file helper functions. */