From patchwork Sat Mar 15 03:15:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 14017707 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 6EF67C282EC for ; Sat, 15 Mar 2025 03:15:58 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 48514280005; Fri, 14 Mar 2025 23:15:56 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 3FC86280004; Fri, 14 Mar 2025 23:15:56 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 1C9AB280005; Fri, 14 Mar 2025 23:15:56 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id EA1DF280003 for ; Fri, 14 Mar 2025 23:15:55 -0400 (EDT) Received: from smtpin05.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id AF4CC141780 for ; Sat, 15 Mar 2025 03:15:56 +0000 (UTC) X-FDA: 83222321112.05.4C1A6E6 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by imf27.hostedemail.com (Postfix) with ESMTP id 010474000C for ; Sat, 15 Mar 2025 03:15:54 +0000 (UTC) Authentication-Results: imf27.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=E2decw82; spf=pass (imf27.hostedemail.com: domain of kees@kernel.org designates 139.178.84.217 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=1742008555; 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:in-reply-to:references:references:dkim-signature; bh=r178xt6oJlNM35hncn5GVtR0lumqQUE22H3urQk21jc=; b=m46RNUaQi00AqTgp82CWTb6YTaRNUyvnKCNJ0P7OE8t2s7Obkvhu8JDEGTWMtnHXTRDrAb 2OFMi4KZy9ACEugbB4luuLXGmuWMimZaPupYJPRfNzJ2ylMfy4R5G1n4VtnDRSJ4Q3hli2 prNWMN6qrs0AnSWN/Uawe1q01qxHW8Q= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1742008555; a=rsa-sha256; cv=none; b=P6tfyOgnnqKWf12QVm5ydkJml2rR50zgiTZ51RFQ04Radfuw2qb8CcL0TqucLrl1DiMFrY JDC3e9SvQSr2876BhXiyaVDE2mdXNggIkZDWS3pSaNLCmwt3AlwYvOD1TOsG9TttJkVViv 6mLqy/cB9HkWG4lXieOyBXtybpVcK+M= ARC-Authentication-Results: i=1; imf27.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=E2decw82; spf=pass (imf27.hostedemail.com: domain of kees@kernel.org designates 139.178.84.217 as permitted sender) smtp.mailfrom=kees@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id 33DE65C57C8; Sat, 15 Mar 2025 03:13:37 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 63672C4AF09; Sat, 15 Mar 2025 03:15:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1742008553; bh=6fauUqJf2RETc23o77eFJUZM9KoHAbkVXnkZpps4aeQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=E2decw82ERVUEzB8Epa5JhaqLbgcc1DQ62K27AWM3sI24cuq7ab/oHUYAOyaeaVeO DyO/eq/x02vrEAs5AO6qkep1I+c23m/ErHVJc9PdR8aTi4Vm1gKXsVk++/enmTOZzL PfXL4lDeb3ncd8kZp4q4JZPIsNxwnRcp+4pAjVhCX3kBHnSt73WPzg0iKAi/z5VmVM 6EPr6WAHNMs1n6SN5zK7ckXH5fvLEkIpp1c8j4V9a78aXVRYdrcOprDEXCqBzQXav0 JhIc25qskgxIcD/Sci/GNzgWeROVwxSnl49e9YSF9DvCeZ3g7UTKG+PvUDHYk+q2Th 3IzrZEf3KOWoA== From: Kees Cook To: Vlastimil Babka Cc: Kees Cook , Miguel Ojeda , "Gustavo A. R. Silva" , Nathan Chancellor , Peter Zijlstra , Nick Desaulniers , Marco Elver , Przemek Kitszel , linux-hardening@vger.kernel.org, Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Roman Gushchin , Hyeonggon Yoo <42.hyeyoo@gmail.com>, Bill Wendling , Justin Stitt , Jann Horn , Linus Torvalds , Greg Kroah-Hartman , Sasha Levin , Jonathan Corbet , Jakub Kicinski , Yafang Shao , Tony Ambardar , Alexander Lobakin , Jan Hendrik Farr , Alexander Potapenko , linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, llvm@lists.linux.dev Subject: [PATCH v4 1/2] compiler_types: Introduce __flex_counter() and family Date: Fri, 14 Mar 2025 20:15:44 -0700 Message-Id: <20250315031550.473587-1-kees@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250315025852.it.568-kees@kernel.org> References: <20250315025852.it.568-kees@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5026; i=kees@kernel.org; h=from:subject; bh=6fauUqJf2RETc23o77eFJUZM9KoHAbkVXnkZpps4aeQ=; b=owGbwMvMwCVmps19z/KJym7G02pJDOlXPjxIjE73nBMiZa7s/XPC1yVaSm9P+sa7ZV2RO7f5t a8Xh2JDRykLgxgXg6yYIkuQnXuci8fb9nD3uYowc1iZQIYwcHEKwER47zEyXPnkmFQj8EN7XpBd S/CzJB4flnDzcxIKSU68Z0Trp794yciw4O+FVc8Sa16bfLbtOyMnFXRT84Tq+jTPKYlF5/azia1 kAgA= X-Developer-Key: i=kees@kernel.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 X-Rspam-User: X-Rspamd-Server: rspam11 X-Rspamd-Queue-Id: 010474000C X-Stat-Signature: jkcbm88in78fwimcwf1haqup476xzft4 X-HE-Tag: 1742008554-832685 X-HE-Meta: U2FsdGVkX1/X1RSbLRpdOSpPV6vrXvz3YCq5TbxD21eBOgg8w5FOQmOLYvhHKNvkmaVGu3pe9HVKGTRCRjnVA6nX83x3Coo+yisfC90UpDJqV6T02blwshnJQENmiSAMR5hxyC51o6Qafmzu4lLFKkp/BnDprqDjSOiNIiiLnbX1LhJuCwAU9mldgc911KGHxWxoDuCOy3mQq/nBzbXhXoY78s3sD80MfVNi2yMv0wvFBQyzFbFzQF53OjJw/tGGSxR0IqqaJRtDS4PdxCNCYGJK478+6i0iNjj3Kb87nSlMgoLo3YxVD5oRLdnHvO/pdYKa7GJVv7gKGVi99rXSQmJfA7boAj5MzBjNPFRjj+9KWlaaXItM9t90BC06fiHNTluIs32o22o1DwnFwiHD3LnDhkKIYcCmawE7sKqpvT9hTyo58nxu6MyN9vaKIfJUxTXpY+9XxMHThK8s7xUK5m+qE+zPS0w6U1u4IWkUJlwNzzxRI9KSmlnZg6y2kxm6tSc8od1mx5w6HlHatIJtE/Eji1PoYyH/gPtV/jlOzOg5/ccRWC9n2RZIXl+dnFPhJjrxmkG/oT7+KDhhtcf1VOVpV/bqDCARgaJHDXt8OzydraamgNf1R/CTmjIKyTNoHwM79R4eZCxSmQm2x8tt6659+DpNCX15INAifjLesv2AKwBc0tCAPEKocRJ/NhGXb13VOU09APUR0WAO8pgMrAhIbGLfudbt6mlENOJn0v4q1/2wMyBXn9vTy9Ebha8J45ewitwB9pR54DsONXBsH+bNrIvxauFVTSO5LTvb4JLRXPW21cRX7HNfaGicGdTAVu/YUGS0sYP6LLCoqwYN0HTRw+vFC07WM33VbU7C4ayHcH/Xk6Kg2utfnIri0q4DfRlfGpDV+JDdNetdbRA3kGFH0d1Ra/8LU9H/nM7DdeGhKZDcJv8dl/lu1/2vpszpYxNgqQjJYJvcNd61G6s WXqUo2zC Q+2xpAAN9PM7PNDmFVr9fUs5Sb3/3jTuN+/v7Jf6M3AXmYU1i9aOggf48ChQAChx1NBBfAzSsvl9AMabrZPPkL4drESGBXxAPBPciywbuoN4yJkGOPDw0dkHSkXbF/FHb89K1q0545rTuqv+XUmGuXqJZrjKIxCiKGJOFHozabw6pokmqhkNAZSdvLFOHrfIyiY3ILgQprQdRCDUW0Inntm+ZMWZeomccPZtHVbbOwzF2/3SXPV/hEaCeXU/DkahIADS+gT8K1SXjS5UV0pjbxsycMKl0KJG2mDQfUEAYBIwTIPjq3mg+36upwWepvVXGHoQwjrX1LqHZcQQQmiUvAteZhWYc+6DD7hZelnRIdvWAqPnLhXTtaupMed4D8fNvmw7Tgq4gj1TcyJzuiF0Qbsj1Z6RIHBtAS8KQBJW7BfG/noQvpNbSggKYwpedl9bnxbwPKXmZKQbXaMvqnrMq5sy46xoq2ulMNeFvPUsjaMP7mGRRNcIhHQTYntNrsUFDzyidLQtKAI2oGlrv1hBiCsgRfhSecO/OsTFnyqCgBBKCOAnrbWJ0L/hvwA== 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: Introduce __flex_counter() which wraps __builtin_counted_by_ref(), as newly introduced by GCC[1] and Clang[2]. Use of __flex_counter() allows access to the counter member of a struct's flexible array member when it has been annotated with __counted_by(). Introduce typeof_flex_counter(), can_set_flex_counter(), and set_flex_counter() to provide the needed _Generic() wrappers to get sane results out of __flex_counter(). For example, with: struct foo { int counter; short array[] __counted_by(counter); } *p; __flex_counter(p->array) will resolve to: &p->counter typeof_flex_counter(p->array) will resolve to "int". (If p->array was not annotated, it would resolve to "size_t".) can_set_flex_counter(p->array, COUNT) is the same as: COUNT <= type_max(p->counter) && COUNT >= type_min(p->counter) (If p->array was not annotated it would return true since everything fits in size_t.) set_flex_counter(p->array, COUNT) is the same as: p->counter = COUNT; (It is a no-op if p->array is not annotated with __counted_by().) Signed-off-by: Kees Cook --- Cc: Miguel Ojeda Cc: "Gustavo A. R. Silva" Cc: Nathan Chancellor Cc: Peter Zijlstra Cc: Nick Desaulniers Cc: Marco Elver Cc: Przemek Kitszel Cc: linux-hardening@vger.kernel.org --- include/linux/compiler_types.h | 31 +++++++++++++++++++++++++++++ include/linux/overflow.h | 36 ++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index 981cc3d7e3aa..8b45ecfad5b1 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -453,6 +453,37 @@ struct ftrace_likely_data { #define __annotated(var, attr) (false) #endif +/* + * Optional: only supported since gcc >= 15, clang >= 19 + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fcounted_005fby_005fref + * clang: https://github.com/llvm/llvm-project/pull/102549 + */ +#if __has_builtin(__builtin_counted_by_ref) +/** + * __flex_counter() - Get pointer to counter member for the given + * flexible array, if it was annotated with __counted_by() + * @FAM: Pointer to flexible array member of an addressable struct instance + * + * For example, with: + * + * struct foo { + * int counter; + * short array[] __counted_by(counter); + * } *p; + * + * __flex_counter(p->array) will resolve to &p->counter. + * + * Note that Clang may not allow this to be assigned to a separate + * variable; it must be used directly. + * + * If p->array is unannotated, this returns (void *)NULL. + */ +#define __flex_counter(FAM) __builtin_counted_by_ref(FAM) +#else +#define __flex_counter(FAM) ((void *)NULL) +#endif + /* * Some versions of gcc do not mark 'asm goto' volatile: * diff --git a/include/linux/overflow.h b/include/linux/overflow.h index 0c7e3dcfe867..e2b81cb5576e 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -440,4 +440,40 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) #define DEFINE_FLEX(TYPE, NAME, MEMBER, COUNTER, COUNT) \ _DEFINE_FLEX(TYPE, NAME, MEMBER, COUNT, = { .obj.COUNTER = COUNT, }) +/** + * typeof_flex_counter() - Return the type of the counter variable of a given + * flexible array member annotated by __counted_by(). + * @FAM: Pointer to the flexible array member within a given struct. + * + * Returns "size_t" if no annotation exists. + */ +#define typeof_flex_counter(FAM) \ + typeof(_Generic(__flex_counter(FAM), \ + void *: (size_t)0, \ + default: *__flex_counter(FAM))) + +/** can_set_flex_counter() - Check if the counter associated with the given + * flexible array member can represent a value. + * @FAM: Pointer to the flexible array member within a given struct. + * @COUNT: Value to check against the __counted_by annotated @FAM's counter. + */ +#define can_set_flex_counter(FAM, COUNT) \ + (!overflows_type(COUNT, typeof_flex_counter(FAM))) + +/** + * set_flex_counter() - Set the counter associated with the given flexible + * array member that has been annoated by __counted_by(). + * @FAM: Pointer to the flexible array member within a given struct. + * @COUNT: Value to store to the __counted_by annotated @FAM's counter. + * + * This is a no-op if no annotation exists. Count needs to be checked with + * can_set_flex_counter(FAM, COUNT) before using this function. + */ +#define set_flex_counter(FAM, COUNT) \ +({ \ + *_Generic(__flex_counter(FAM), \ + void *: &(size_t){ 0 }, \ + default: __flex_counter(FAM)) = (COUNT); \ +}) + #endif /* __LINUX_OVERFLOW_H */