From patchwork Fri Feb 28 19:50:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 13996993 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2063CC282C6 for ; Fri, 28 Feb 2025 19:50:44 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 896F6280003; Fri, 28 Feb 2025 14:50:43 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 845A0280001; Fri, 28 Feb 2025 14:50:43 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 6BF36280003; Fri, 28 Feb 2025 14:50:43 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 4BC66280001 for ; Fri, 28 Feb 2025 14:50:43 -0500 (EST) Received: from smtpin29.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id C79BCA389C for ; Fri, 28 Feb 2025 19:50:42 +0000 (UTC) X-FDA: 83170395924.29.F190225 Received: from tor.source.kernel.org (tor.source.kernel.org [172.105.4.254]) by imf18.hostedemail.com (Postfix) with ESMTP id 1ABA11C000A for ; Fri, 28 Feb 2025 19:50:40 +0000 (UTC) Authentication-Results: imf18.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=NNSV9REg; spf=pass (imf18.hostedemail.com: domain of kees@kernel.org designates 172.105.4.254 as permitted sender) smtp.mailfrom=kees@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1740772241; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:references:dkim-signature; bh=IcLmA8DSeFIqsxFGgC4V9l/pG8q/CkAJAu2hasV6b7Q=; b=n2yw7bzge/n9eZX44pGcMZ79qtbq7vxeaC9N8sAhhrwTw8OXzjvd/nCE5Nn6AQzDDwBBgj 7wk67KfVgH7lF29mu/RQeTxw3iEIG/61UKNAYilxnONoFaXqpqJzVq0ErX36u9YXSOWQgL fGl8ABkJy6B9Jfhh5ZnxPDG6O1b4TZY= ARC-Authentication-Results: i=1; imf18.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=NNSV9REg; spf=pass (imf18.hostedemail.com: domain of kees@kernel.org designates 172.105.4.254 as permitted sender) smtp.mailfrom=kees@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1740772241; a=rsa-sha256; cv=none; b=CV6S6lOY0hWzsxrGBAejfsrFULcKrtJh3Sq0gO5UXFEEk0EKltak2iRCPGU4ZrocIlmisK 9dLSgYrd+aUW1DspHXIQ5KzNi8omNi7jxsUsQnziYosqbQDBFqxb8qsn3kAgolW8XA4tJs JfmVhnkpG+rHOHr1qn3cmVuteT6srjw= Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by tor.source.kernel.org (Postfix) with ESMTP id 4A8616114A; Fri, 28 Feb 2025 19:50:30 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E60EC4CEE9; Fri, 28 Feb 2025 19:50:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1740772238; bh=1oTYdMLj5IJV7VGpD5+wlKsa4biWQMpU+M06wbYFhIo=; h=From:To:Cc:Subject:Date:From; b=NNSV9REg9Bw7j6BcHsc5c96iIjmxtrvK6/O2TY92s+YnhYOZMX6JJLeWl3DbsX68o UG8qnu3QSMo6d9pxOGANjJzTooD/H9tBE+O6wfpecwg7EaOPdqAW6aR4vrC1VoCbZC jCo0CWla8MGYYgPRDhvM823n5pThGNMYYa+h4g0CA4eNAyDLgJs6ehaX0AZ9AnzK3y U7MyhzEsGnshu9St8I9bSQTosUNq8exGX+6Y4ex5G936mgiOpQZ7hi0KRFDsVjuiN/ YWgkBSfb39zwG6MA+V83XX2RDr03GfSffShQVgccKmmhCcXNmkKBRxk3Okx0/srYxY FTfYYFx1e2OAg== From: Kees Cook To: Al Viro Cc: Kees Cook , kernel test robot , "Gustavo A. R. Silva" , Andrew Morton , Peter Zijlstra , Thomas Gleixner , "Rafael J. Wysocki" , Arnd Bergmann , Christophe Leroy , Mel Gorman , Aleksa Sarai , Christian Brauner , Alexander Potapenko , Catalin Marinas , linux-hardening@vger.kernel.org, Sebastian Andrzej Siewior , Alice Ryhl , linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH] uaccess: Introduce ucopysize.h Date: Fri, 28 Feb 2025 11:50:23 -0800 Message-Id: <20250228195019.work.296-kees@kernel.org> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6926; i=kees@kernel.org; h=from:subject:message-id; bh=1oTYdMLj5IJV7VGpD5+wlKsa4biWQMpU+M06wbYFhIo=; b=owGbwMvMwCVmps19z/KJym7G02pJDOmHhOstV3qUHGmv73j1crmKgRWbgnLetzi2rXx7u1a87 nrVXC3aUcrCIMbFICumyBJk5x7n4vG2Pdx9riLMHFYmkCEMXJwCMJGmBIbfbIK7/dvEfL4GFXF3 Mq7XCf9oESi4/Z3u46Ov7mxxCAg+x8iwzro/V9/fT3zNm8O1HJ+DOGYV+tXZV7qxuAiIzVx6qIM bAA== X-Developer-Key: i=kees@kernel.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 X-Rspam-User: X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: 1ABA11C000A X-Stat-Signature: ij1rn49gnnraqynaa41zspw5kx87je6u X-HE-Tag: 1740772240-367705 X-HE-Meta: U2FsdGVkX18A9J8/KMIcwhTwaYgvAlA0/Ma6lKPs22q+LYQBzSZpjfz3kbyqNIH3u3/xi3qYT2/rSNn34bdHh9AoaUC8AGn+C6oBOEXwjhcNNKJXZ96EIfS8kxTyZ833L17IqvPmI6CeFyuhQdNX4vo9LCKCGBMY+A/jON4j6Yseo5ufiNGSHi2p6A6U9u9wjOwKaKjaQytk14bBeFNp8amg3WaPInl1RKzgVjd+Iq8+e4pkt9K88Xz3NMWQ5pk7qh50668F+h6tjQXjZiqKViSS59FfD+vKWhgokjXNBLofMXB3BQP3UmenC8Vtc2qBEAzxOCBNkW8qf/Oa4B1D22zogDk/hHvbZUN2vjg5dOZg2YYB35zk51pEIKzu32TX3yGInJt3vMwEm0FHGauZCPGzI1XwpB4zJr92gOOZPMrAzUZi7fVu1vcK364EQ63mOjGo+1vOrQ795L6qGOoM+3XVQT3ZZMEdG84vMlxeLfAljw2IRKyzIxE/0HxqbDgAhpJ4zmLbOH3fk1n8EmwAgy+b7O4biD0Kgs4U3ch8SODTCwifr5Xg48QE+drF+fvMT2A8dkFSgrGTvE+notD/Zl8whMsoMGWYqwCDBuaF9JADaTZUWGwKgPIplLERHnuoHiTxE2O1mfxjq7tVcNSxr2iO2pT34DymEf27t+etvIxoWhIUkWBhWkO3wNaoK1aso7ieH4aeUlT6TMUgST9zNRrqjR67mniw7I0SEP4fPbwl9d8/URaByXlhqSIhBTNqVqSKI99nGdzGrjhbSXX+i96SSG19+uFB2QCb2d5alnqBTv5ycB8epbf7JDR8XHE1ect7nJf0keBCyHqUpvYBUrejcYcRo1uiYAImYZNaLigX9VEIY9RtkEGiD6hK9vdhQRhB+n7WkCEFa4jh8XK23hQd6cVSBp4PiD5rwKk7T00x3B0rFJ2+Nt4wMW2aKwRbbhKptqLitg9hEbDvUy5 Cvd+1z5W eyB6rbmpF0IsqvCSPnCtjf+R7GYHocWRWwtsqDN+6oSwjB3GrlT6ae5xfDDB5dOqxmTcSnA/gCb1IN81T9nUbUJMNLmwc+9BzT0EO5FB5HK7qS3+nszy00If4pz6z6ti6q/S/fvlTweJD1Nosla2mxaHeT7MIs+dw6hASJpfcpv16xRgUFFiyTisDozdInakdDbdPT2ZtKEH3CuMgqs14dmMn6bMaoWB5mgnOH2jtFfwE547Dzyarrx2p2HTod8UPhbzUYmkxJQLCQP6DFULUjdcPwjXvW0+yS+PF/0fX3AeUV3XxKRLzKIjZipuZRKgmfAGINyBXjNjbeLcXKpZuPScTW3y+DyjvHM27o1P/42jg6jEQeDgouPXh5nd3Ox7S6b5gVp5AATey2tWnbCy5gz6WpnDS373TWU7Y0iUEbWcjUV5NDpCYC1BAvSmD08uC7F+AUfMosAYQqCMndtMuRtCvGeNTkniN6Hj4xL0r4EI5+cUy8gFYlFq/+NxlStBBEE2WBcmxNANigRl3l+TOWDyeZgJ58Um6OdoVw8hn0dUadxdQcaE2CGIJHzy89roZrfO7t3eY75B1Vs/QMd36hgyTlgGuLy9JOc1hWEfVGMysvknx0LrYGbp1aXJEGk3TBDdAgcf3Ms9LFPU3ZFt32Gdgc4MC6VtprRs86pHjTcM2l5MThgHLzHw6Wkv3pS2jBLOJ X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: The object size sanity checking macros that uaccess.h and uio.h use have been living in thread_info.h for historical reasons. Needing to use jump labels for these checks, however, introduces a header include loop under certain conditions. The dependencies for the object checking macros are very limited, but they are used by separate header files, so introduce a new header that can be used directly by uaccess.h and uio.h. As a result, this also means thread_info.h (which is rather large) and be removed from those headers. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202502281153.TG2XK5SI-lkp@intel.com/ Signed-off-by: Kees Cook --- I'll carry this in the hardening tree since the usercopy hardening changes depend on it... Cc: Alexander Viro Cc: "Gustavo A. R. Silva" Cc: Andrew Morton Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: "Rafael J. Wysocki" Cc: Arnd Bergmann Cc: Christophe Leroy Cc: Mel Gorman Cc: Aleksa Sarai Cc: Christian Brauner Cc: Alexander Potapenko Cc: Catalin Marinas Cc: linux-hardening@vger.kernel.org --- MAINTAINERS | 1 + include/linux/thread_info.h | 48 ------------------------------- include/linux/uaccess.h | 2 +- include/linux/ucopysize.h | 56 +++++++++++++++++++++++++++++++++++++ include/linux/uio.h | 2 +- mm/usercopy.c | 2 +- 6 files changed, 60 insertions(+), 51 deletions(-) create mode 100644 include/linux/ucopysize.h diff --git a/MAINTAINERS b/MAINTAINERS index 25c86f47353d..a1900962ced9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12586,6 +12586,7 @@ F: Documentation/ABI/testing/sysfs-kernel-warn_count F: arch/*/configs/hardening.config F: include/linux/overflow.h F: include/linux/randomize_kstack.h +F: include/linux/ucopysize.h F: kernel/configs/hardening.config F: lib/usercopy_kunit.c F: mm/usercopy.c diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index cf2446c9c30d..dd925d84fa46 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -217,54 +217,6 @@ static inline int arch_within_stack_frames(const void * const stack, } #endif -#ifdef CONFIG_HARDENED_USERCOPY -extern void __check_object_size(const void *ptr, unsigned long n, - bool to_user); - -static __always_inline void check_object_size(const void *ptr, unsigned long n, - bool to_user) -{ - if (!__builtin_constant_p(n)) - __check_object_size(ptr, n, to_user); -} -#else -static inline void check_object_size(const void *ptr, unsigned long n, - bool to_user) -{ } -#endif /* CONFIG_HARDENED_USERCOPY */ - -extern void __compiletime_error("copy source size is too small") -__bad_copy_from(void); -extern void __compiletime_error("copy destination size is too small") -__bad_copy_to(void); - -void __copy_overflow(int size, unsigned long count); - -static inline void copy_overflow(int size, unsigned long count) -{ - if (IS_ENABLED(CONFIG_BUG)) - __copy_overflow(size, count); -} - -static __always_inline __must_check bool -check_copy_size(const void *addr, size_t bytes, bool is_source) -{ - int sz = __builtin_object_size(addr, 0); - if (unlikely(sz >= 0 && sz < bytes)) { - if (!__builtin_constant_p(bytes)) - copy_overflow(sz, bytes); - else if (is_source) - __bad_copy_from(); - else - __bad_copy_to(); - return false; - } - if (WARN_ON_ONCE(bytes > INT_MAX)) - return false; - check_object_size(addr, bytes, is_source); - return true; -} - #ifndef arch_setup_new_exec static inline void arch_setup_new_exec(void) { } #endif diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index e9c702c1908d..7c06f4795670 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include diff --git a/include/linux/ucopysize.h b/include/linux/ucopysize.h new file mode 100644 index 000000000000..b3e1b875d565 --- /dev/null +++ b/include/linux/ucopysize.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Perform sanity checking for object sizes for uaccess.h and uio.h. */ +#ifndef __LINUX_UCOPYSIZE_H__ +#define __LINUX_UCOPYSIZE_H__ + +#include + +#ifdef CONFIG_HARDENED_USERCOPY +extern void __check_object_size(const void *ptr, unsigned long n, + bool to_user); + +static __always_inline void check_object_size(const void *ptr, unsigned long n, + bool to_user) +{ + if (!__builtin_constant_p(n)) + __check_object_size(ptr, n, to_user); +} +#else +static inline void check_object_size(const void *ptr, unsigned long n, + bool to_user) +{ } +#endif /* CONFIG_HARDENED_USERCOPY */ + +extern void __compiletime_error("copy source size is too small") +__bad_copy_from(void); +extern void __compiletime_error("copy destination size is too small") +__bad_copy_to(void); + +void __copy_overflow(int size, unsigned long count); + +static inline void copy_overflow(int size, unsigned long count) +{ + if (IS_ENABLED(CONFIG_BUG)) + __copy_overflow(size, count); +} + +static __always_inline __must_check bool +check_copy_size(const void *addr, size_t bytes, bool is_source) +{ + int sz = __builtin_object_size(addr, 0); + if (unlikely(sz >= 0 && sz < bytes)) { + if (!__builtin_constant_p(bytes)) + copy_overflow(sz, bytes); + else if (is_source) + __bad_copy_from(); + else + __bad_copy_to(); + return false; + } + if (WARN_ON_ONCE(bytes > INT_MAX)) + return false; + check_object_size(addr, bytes, is_source); + return true; +} + +#endif /* __LINUX_UCOPYSIZE_H__ */ diff --git a/include/linux/uio.h b/include/linux/uio.h index 8ada84e85447..49ece9e1888f 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h @@ -6,8 +6,8 @@ #define __LINUX_UIO_H #include -#include #include +#include #include struct page; diff --git a/mm/usercopy.c b/mm/usercopy.c index 83c164aba6e0..16d63bd010af 100644 --- a/mm/usercopy.c +++ b/mm/usercopy.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include