From patchwork Wed Oct 9 19:10:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 175636 Delivered-To: patch@linaro.org Received: by 2002:a92:7e96:0:0:0:0:0 with SMTP id q22csp1170516ill; Wed, 9 Oct 2019 12:11:14 -0700 (PDT) X-Google-Smtp-Source: APXvYqx5OHyd4BYxQZsqCNvVgfHWkn49FuvlE62Xt8gThsXUu8wfQxJivAT6Gy+W76xfQnkeqgaC X-Received: by 2002:a17:906:c57:: with SMTP id t23mr4330044ejf.219.1570648274856; Wed, 09 Oct 2019 12:11:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570648274; cv=none; d=google.com; s=arc-20160816; b=RtUHf4ORCWYqFHvhjfTwBbpWQPApa8smyWKnK7H/4IhajFfyQfT6G49s08t8amYCAN pxlPPq8fpwcwBiYCIS6vS6WpNf4ggwRatz30EBKJ+0qFAc0mOesAbjgNaUTVihHQd2jS VFvWxwcW30ai3WHKCT/ocqzRue156dCAXljcYyrlGajRWIqWX9qkEkYGBGAm7HHYBehd b4FimM7HZDOw3J1CU95wCLIeFcNwnalbGfBb+Z9KZK6dZ8Udua08CCvpaBF0Q/63gZj2 Krrrehm7nIC8sqZcQPeTozg0teKvMMG/lcvzSoHuX0WiKq0+EUamqUjRqzDSwzAy2BIB A9Zg== 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=eU9mMeBfGQPBg3i6HHq1JYtT46fr4hupgcL++DgRfYQ=; b=WR/DaDWwdFqIJ9M2FqMnH5yjiuR2wsGOz61ChV6wubP0FWQp46C2686+Y5W9h1KETl 06PedjzAB6AoQZkZeURdkVf1tln1BCwMPROtnXKkXzCSVHPY+v9NvVjD1Ozum2PZwHlI 2rpKjvpprZZB64tCgIx749ia9xUdrW6oB0YF5Fbiir6iRqDA5gl5HjmAynGaUbupoE0/ fa+z1S92+gEAgKhDDuuoF8d01VgKosUVEq/QqjDrHvfY/tHfTLe3UpEL/3HPo4KDcIkf rlOaeLgkjQoo6nttKpWiBDMGSj36QvmOwTzK4onZAjh9aSYiqVNgoLpVmPkm54mmnHZR vTtQ== 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 g30si1996732eda.2.2019.10.09.12.11.14; Wed, 09 Oct 2019 12:11:14 -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 S1731792AbfJITLM (ORCPT + 26 others); Wed, 9 Oct 2019 15:11:12 -0400 Received: from mout.kundenserver.de ([212.227.126.187]:42423 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731144AbfJITLK (ORCPT ); Wed, 9 Oct 2019 15:11:10 -0400 Received: from threadripper.lan ([149.172.19.189]) by mrelayeu.kundenserver.de (mreue011 [212.227.15.129]) with ESMTPA (Nemesis) id 1MLzSD-1iaDr11Rab-00HuC6; Wed, 09 Oct 2019 21:11:06 +0200 From: Arnd Bergmann To: Al Viro Cc: linux-kernel@vger.kernel.org, y2038@lists.linaro.org, linux-fsdevel@vger.kernel.org, Arnd Bergmann Subject: [PATCH v6 09/43] compat_ioctl: add compat_ptr_ioctl() Date: Wed, 9 Oct 2019 21:10:09 +0200 Message-Id: <20191009191044.308087-9-arnd@arndb.de> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20191009190853.245077-1-arnd@arndb.de> References: <20191009190853.245077-1-arnd@arndb.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:CIXoOECmE4Ydk1Z/lGazuni0y3AvvhSKErUXxmDj6hoc/lGA6n1 n1JlKtouYc5tmlB+Q0qfvmbnzsEuxX7hKdQa2JHuL5CbZvzjIiuTQGKRq74WhfL6aTIaqQu ugfbzDyybpOxAhTqrHD7Xo3Y+Tnhg9Yme/2A73obzZ+qbRLV76a0k5db+nae2Zl1AsN45CK gtCOqiLMNHBYx/+WpJMug== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1; V03:K0:L2RMaJB5fME=:MXyBXS3UeBoG8NcHVgoKuK MhLtWnuMnfitDST7C/KybKwwmxC8yLd9aolr0idFbtXPC6CbseSRmKmAFb1Wt3gctoigO09TG h0vo3IYCesuUmnVs8SRrAYReBXQ8P15VP6JxgXwhYB/neR6VADupowpTtFKsGUUup6KnROs6+ p+w06FOM7EkxXLz1+aX2BYY8yZ2ObSjaeJMNXYIcjeGRjnfpVNx7vkS+Vc+CkTSFI42dWt8/N f4TNoPEwHoDNUo0Z7ojIFDBgb2QVyD+770070FNgYrip6T0PeQKY2k0Ej2+NzByIfyFeIHclT GFgbbQM5TwJr0p+zOBEhR1+Ehzym4HvGYV8fv0UGrsUKhUGIv3UdLLskYKL0/q35fBVKWHgW1 KvD477V5wvPX+Z7YcSsvwCSJ5OXdr9XNn5yjvDLYwqixkUuJYFEHaHM+zgTkfF4xvM6xVDQ1e fgm3jqHglitHN/q0GWd4Ji7EKRQhA+6p4ZGc1lGKG/8oCUDAQe+x/GRL5uH2BbyHkq65RnCOZ LOB0bFrfbVEbEML7Q+hKl1fkz08eZXcWVGgj02M/aV2c0hGRh184tYG0HSa8oqY3LPWCY0hcr /H730wsVLn9EycoOWqgo09mXJd0YHb5ks/eJcTHJWWwDuy+qlZuS12fvv0A7H3E4Ks5K5xbW3 1cxSb2Nk9D23xcqeC4QV/mw9VLArrFmZTkMoPr8Uh3RGaEMrvleEOUzu2RaFC1qgrqoDQP/yQ jDm5nwfmDFYxuYrJ41njHCzr1VQAU0yCWAhF6ZB8z9r3oftMA77eUqD3xHW1ow52dlByyaMpw yQEZs3SjRLApN8tx+F8n2kc0hrXCP/2EYILdsSZ48BoEOqlucRA1rIYz+ZQy5rC8uxzvXklrj w1dVDe9K83tZ//NSsSKg== 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 e0d909d35763..0b4d8fc79e0f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1727,6 +1727,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. */