From nobody Fri Dec 19 19:23:34 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6263A2EA159; Wed, 3 Dec 2025 23:30:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764804637; cv=none; b=rSQmpm5o5DxKAqr88Sb0+Odqdq1xFXpXF5SJ+rXjErVIoPE0AL2e4wIlWL7p00l27TAPu8ai2QLkN/7Qf5waD4rPVYBlWa+UaPDbkDD3Zd1TzXU4SiQ0bKCx40/24WBdYvxvJVypiUGlBjZy9rK8+cvDdkF/s0IqKb1GpiANftY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764804637; c=relaxed/simple; bh=b70/KGt4+G3yUdizOvICLD5U1fsug4s3g9xHogw1SUE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=iHfcLvw+0qO0zB4pxrjAX7EadeStEQpwOkQjtlqcKi+d+1iejYitSLqOX385Ke7SCtO0P4U/L4jzqG16GdA+ueMgAuhAqwmCSGi2LCM1VrN3JK6TNrsT8cVtP2KtDSMZhtcelsrQzhZdhsuNthERP61oBCyRjYTSXgStfq+doN0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=R9nAj91d; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="R9nAj91d" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F0DF8C4CEF5; Wed, 3 Dec 2025 23:30:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764804637; bh=b70/KGt4+G3yUdizOvICLD5U1fsug4s3g9xHogw1SUE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=R9nAj91dfGyTnOUBJPoJPhGYAxKJ7ud8/GAvnlEj5Knst1Ffx8Vp/swNMKMPimAO0 tXzYYuXUhMqkCZAf1yheWhyqYmdW76P8q/UF1g/ZWOsSKr+Fo5UhjRv6GzxvBj4YL/ DDISbhgsZWTUnQ7MBsxYC4gGatObZQy3JuDkqbh5NdOLhf/XBh5mBm2BUYET34g5Rr BiFt53ElbYC4DNWYdAz5tkzZc6AykXlQyLWEo5/sB8XA2XmAruOFn72oF0VwkxIx/X LwRmSKJcalRuK4HTTHLGIBHKNq+IWQuV7zFlrwG+gWnSLf+5PCpDop6HfDnbw9g6ZA S8GMyd7419nVg== From: Kees Cook To: Vlastimil Babka Cc: Kees Cook , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Roman Gushchin , Hyeonggon Yoo <42.hyeyoo@gmail.com>, "Gustavo A . R . Silva" , Bill Wendling , Justin Stitt , Jann Horn , Przemek Kitszel , Marco Elver , Linus Torvalds , Greg Kroah-Hartman , Sasha Levin , linux-mm@kvack.org, Randy Dunlap , Miguel Ojeda , Matthew Wilcox , John Hubbard , Joe Perches , Vegard Nossum , Harry Yoo , Nathan Chancellor , Peter Zijlstra , Nick Desaulniers , Jonathan Corbet , Jakub Kicinski , Yafang Shao , Tony Ambardar , Alexander Lobakin , Jan Hendrik Farr , Alexander Potapenko , linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, linux-doc@vger.kernel.org, llvm@lists.linux.dev Subject: [PATCH v6 1/5] slab: Introduce kmalloc_obj() and family Date: Wed, 3 Dec 2025 15:30:31 -0800 Message-Id: <20251203233036.3212363-1-kees@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251203233029.it.641-kees@kernel.org> References: <20251203233029.it.641-kees@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6780; i=kees@kernel.org; h=from:subject; bh=b70/KGt4+G3yUdizOvICLD5U1fsug4s3g9xHogw1SUE=; b=owGbwMvMwCVmps19z/KJym7G02pJDJkGJyRdT0dZKVzbqX/13sW8G0Y9t5792Lj74ccHToeWy B41mzt9b0cpC4MYF4OsmCJLkJ17nIvH2/Zw97mKMHNYmUCGMHBxCsBEMjUYGX61330w888Snyjf LI2QN2cnCX7Wilml9/iFq3CKymy1+2uBKjQWzX5stLx/dUvRkUuCvyed2H75z43s/c4ftt65Z36 FjQ0A X-Developer-Key: i=kees@kernel.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce type-aware kmalloc-family helpers to replace the common idioms for single object and arrays of objects allocation: ptr =3D kmalloc(sizeof(*ptr), gfp); ptr =3D kmalloc(sizeof(struct some_obj_name), gfp); ptr =3D kzalloc(sizeof(*ptr), gfp); ptr =3D kmalloc_array(count, sizeof(*ptr), gfp); ptr =3D kcalloc(count, sizeof(*ptr), gfp); These become, respectively: ptr =3D kmalloc_obj(*ptr, gfp); ptr =3D kmalloc_obj(*ptr, gfp); ptr =3D kzalloc_obj(*ptr, gfp); ptr =3D kmalloc_objs(*ptr, count, gfp); ptr =3D kzalloc_objs(*ptr, count, gfp); Beyond the other benefits outlined below, the primary ergonomic benefit is the elimination of needing "sizeof" nor the type name, and the enforcement of assignment types (they do not return "void *", but rather a pointer to the type of the first argument). The type name _can_ be used, though, in the case where an assignment is indirect (e.g. via "return"). This additionally allows[1] variables to be declared via __auto_type: __auto_type ptr =3D kmalloc_obj(struct foo, gfp); Internal introspection of the allocated type now becomes possible, allowing for future alignment-aware choices to be made by the allocator and future hardening work that can be type sensitive. For example, adding __alignof(*ptr) as an argument to the internal allocators so that appropriate/efficient alignment choices can be made, or being able to correctly choose per-allocation offset randomization within a bucket that does not break alignment requirements. Link: https://lore.kernel.org/all/CAHk-=3DwiCOTW5UftUrAnvJkr6769D29tF7Of79g= UjdQHS_TkF5A@mail.gmail.com/ [1] Signed-off-by: Kees Cook --- Cc: Vlastimil Babka Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Cc: Andrew Morton Cc: Roman Gushchin Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com> Cc: Gustavo A. R. Silva Cc: Bill Wendling Cc: Justin Stitt Cc: Jann Horn Cc: Przemek Kitszel Cc: Marco Elver Cc: Linus Torvalds Cc: Greg Kroah-Hartman Cc: Sasha Levin Cc: linux-mm@kvack.org --- Documentation/process/deprecated.rst | 24 ++++++++++++ include/linux/slab.h | 58 ++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/Documentation/process/deprecated.rst b/Documentation/process/d= eprecated.rst index 1f7f3e6c9cda..91c628fa2d59 100644 --- a/Documentation/process/deprecated.rst +++ b/Documentation/process/deprecated.rst @@ -372,3 +372,27 @@ The helper must be used:: DECLARE_FLEX_ARRAY(struct type2, two); }; }; + +Open-coded kmalloc assignments for struct objects +------------------------------------------------- +Performing open-coded kmalloc()-family allocation assignments prevents +the kernel (and compiler) from being able to examine the type of the +variable being assigned, which limits any related introspection that +may help with alignment, wrap-around, or additional hardening. The +kmalloc_obj()-family of macros provide this introspection, which can be +used for the common code patterns for single, array, and flexible object +allocations. For example, these open coded assignments:: + + ptr =3D kmalloc(sizeof(*ptr), gfp); + ptr =3D kzalloc(sizeof(*ptr), gfp); + ptr =3D kmalloc_array(count, sizeof(*ptr), gfp); + ptr =3D kcalloc(count, sizeof(*ptr), gfp); + ptr =3D kmalloc(sizeof(struct foo, gfp); + +become, respectively:: + + ptr =3D kmalloc_obj(*ptr, gfp); + ptr =3D kzalloc_obj(*ptr, gfp); + ptr =3D kmalloc_objs(*ptr, count, gfp); + ptr =3D kzalloc_objs(*ptr, count, gfp); + __auto_type ptr =3D kmalloc_obj(struct foo, gfp); diff --git a/include/linux/slab.h b/include/linux/slab.h index cf443f064a66..726457daedbd 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -12,6 +12,7 @@ #ifndef _LINUX_SLAB_H #define _LINUX_SLAB_H =20 +#include #include #include #include @@ -965,6 +966,63 @@ static __always_inline __alloc_size(1) void *kmalloc_n= oprof(size_t size, gfp_t f void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node); #define kmalloc_nolock(...) alloc_hooks(kmalloc_nolock_noprof(__VA_ARGS_= _)) =20 +/** + * __alloc_objs - Allocate objects of a given type using + * @KMALLOC: which size-based kmalloc wrapper to allocate with. + * @GFP: GFP flags for the allocation. + * @TYPE: type to allocate space for. + * @COUNT: how many @TYPE objects to allocate. + * + * Returns: Newly allocated pointer to (first) @TYPE of @COUNT-many + * allocated @TYPE objects, or NULL on failure. + */ +#define __alloc_objs(KMALLOC, GFP, TYPE, COUNT) \ +({ \ + const size_t __obj_size =3D size_mul(sizeof(TYPE), COUNT); \ + (TYPE *)KMALLOC(__obj_size, GFP); \ +}) + +/** + * kmalloc_obj - Allocate a single instance of the given type + * @VAR_OR_TYPE: Variable or type to allocate. + * @GFP: GFP flags for the allocation. + * + * Returns: newly allocated pointer to a @VAR_OR_TYPE on success, or NULL + * on failure. + */ +#define kmalloc_obj(VAR_OR_TYPE, GFP) \ + __alloc_objs(kmalloc, GFP, typeof(VAR_OR_TYPE), 1) + +/** + * kmalloc_objs - Allocate an array of the given type + * @VAR_OR_TYPE: Variable or type to allocate an array of. + * @COUNT: How many elements in the array. + * @FLAGS: GFP flags for the allocation. + * + * Returns: newly allocated pointer to array of @VAR_OR_TYPE on success, + * or NULL on failure. + */ +#define kmalloc_objs(VAR_OR_TYPE, COUNT, GFP) \ + __alloc_objs(kmalloc, GFP, typeof(VAR_OR_TYPE), COUNT) + +/* All kzalloc aliases for kmalloc_(obj|objs|flex). */ +#define kzalloc_obj(P, GFP) \ + __alloc_objs(kzalloc, GFP, typeof(P), 1) +#define kzalloc_objs(P, COUNT, GFP) \ + __alloc_objs(kzalloc, GFP, typeof(P), COUNT) + +/* All kvmalloc aliases for kmalloc_(obj|objs|flex). */ +#define kvmalloc_obj(P, GFP) \ + __alloc_objs(kvmalloc, GFP, typeof(P), 1) +#define kvmalloc_objs(P, COUNT, GFP) \ + __alloc_objs(kvmalloc, GFP, typeof(P), COUNT) + +/* All kvzalloc aliases for kmalloc_(obj|objs|flex). */ +#define kvzalloc_obj(P, GFP) \ + __alloc_objs(kvzalloc, GFP, typeof(P), 1) +#define kvzalloc_objs(P, COUNT, GFP) \ + __alloc_objs(kvzalloc, GFP, typeof(P), COUNT) + #define kmem_buckets_alloc(_b, _size, _flags) \ alloc_hooks(__kmalloc_node_noprof(PASS_BUCKET_PARAMS(_size, _b), _flags, = NUMA_NO_NODE)) =20 --=20 2.34.1 From nobody Fri Dec 19 19:23:34 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 624DF2E1EE0; Wed, 3 Dec 2025 23:30:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764804637; cv=none; b=gsOnaSWDiMlPS6iSbxMW0kjATWffNvrnMeLf9+KbBYT4s9BhoyAUlw523cVC91b9GVCAIO97GbyqbHICofHS2d6RfcSAeTpyVLiwckGC32pHBbSzIbwUIGcbLJFQUd7rP44SmV6/+1v1M0Omw3nGg7dHj3QdXdk9Pdq4cAxYEIU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764804637; c=relaxed/simple; bh=+af9Qrl81jzQeC8vw0DiKskxnHYHklRLaViyotNOrs8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tBAzT8EOWth7TeNKrdEzWttpFXpMLXmRh7K+gXUzqXpHuNpOXwPqzfQHkUC3gLyGA+zSVVFzRuqDu8kDXVmZSWjbwxSGMBnSe0Rw7MhZ4HkjcwTr4yUEmP94NJ1C5bH1upOJXKYgF8RCoMfpO+29SCfTADdbz//CXdjSEIp+MVo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TTSGKzFD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TTSGKzFD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1CB03C4CEFB; Wed, 3 Dec 2025 23:30:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764804637; bh=+af9Qrl81jzQeC8vw0DiKskxnHYHklRLaViyotNOrs8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TTSGKzFDZcQCzCkHsA0QD/1UM2l83yGCYfNGL2ubDFhu5/qeOqXuKKuQqZE7chn1+ wQUHvKKZWhk93Crwejf1aRATHApj/RIA9T9v2yzKOIfpvzYXlCiX3vuLOg/sG31hSz JJnA1bl6492zszZWShNQLqIaQkToFRRiUTlckUtfHB6cy1MqEx8EV1bexU9WfrMzer f/j5Ey+0A5xveVQFv+1s1JAg4qLKxoY3aUF2o4hgNPxf/Z8P7HaTzq4N80gCluMTsU 5iqc0SENnfMz0CvtMWuNavf+s6+0x7XcoVJKjYZM88aWE2M3c4wF5DMMeTylnovfG7 06TNKJfZlbo1w== From: Kees Cook To: Vlastimil Babka Cc: Kees Cook , Andy Whitcroft , Joe Perches , Dwaipayan Ray , Lukas Bulwahn , Linus Torvalds , Randy Dunlap , Miguel Ojeda , Przemek Kitszel , "Gustavo A. R. Silva" , Matthew Wilcox , John Hubbard , Christoph Lameter , Marco Elver , Vegard Nossum , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Roman Gushchin , Harry Yoo , Bill Wendling , Justin Stitt , Jann Horn , Greg Kroah-Hartman , Sasha Levin , linux-mm@kvack.org, Nathan Chancellor , Peter Zijlstra , Nick Desaulniers , Jonathan Corbet , Jakub Kicinski , Yafang Shao , Tony Ambardar , Alexander Lobakin , Jan Hendrik Farr , Alexander Potapenko , linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, linux-doc@vger.kernel.org, llvm@lists.linux.dev Subject: [PATCH v6 2/5] checkpatch: Suggest kmalloc_obj family for sizeof allocations Date: Wed, 3 Dec 2025 15:30:32 -0800 Message-Id: <20251203233036.3212363-2-kees@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251203233029.it.641-kees@kernel.org> References: <20251203233029.it.641-kees@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3354; i=kees@kernel.org; h=from:subject; bh=+af9Qrl81jzQeC8vw0DiKskxnHYHklRLaViyotNOrs8=; b=owGbwMvMwCVmps19z/KJym7G02pJDJkGJyTv9C7XFGXkFdC7we0hu+rcOSf++jRpTnn3BRHPt 5c9zp/eUcrCIMbFICumyBJk5x7n4vG2Pdx9riLMHFYmkCEMXJwCMBGxyQx/xV2+miz81fON7f6+ 2KR5uzQO/j8lw/ym6/hE8ZyDycs+bWNkOPDaslVXY7uKeBQvU9LTrE1t+e7ZKwP3vRKdUnPn5tI /fAA= X-Developer-Key: i=kees@kernel.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" To support shifting away from sized allocation towards typed allocations, suggest the kmalloc_obj family of macros when a sizeof() is present in the argument lists. Signed-off-by: Kees Cook --- Cc: Andy Whitcroft Cc: Joe Perches Cc: Dwaipayan Ray Cc: Lukas Bulwahn --- scripts/checkpatch.pl | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index d58ca9655ab7..a8cdfb502ccc 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -7258,17 +7258,42 @@ sub process { "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); } =20 -# check for (kv|k)[mz]alloc with multiplies that could be kmalloc_array/kv= malloc_array/kvcalloc/kcalloc +# check for (kv|k)[mz]alloc that could be kmalloc_obj/kvmalloc_obj/kzalloc= _obj/kvzalloc_obj + if ($perl_version_ok && + defined $stat && + $stat =3D~ /^\+\s*($Lval)\s*\=3D\s*(?:$balanced_parens)?\s*((?:kv|k)= [mz]alloc)\s*\(\s*($FuncArg)\s*,/) { + my $oldfunc =3D $3; + my $a1 =3D $4; + my $newfunc =3D "kmalloc_obj"; + $newfunc =3D "kvmalloc_obj" if ($oldfunc eq "kvmalloc"); + $newfunc =3D "kvzalloc_obj" if ($oldfunc eq "kvzalloc"); + $newfunc =3D "kzalloc_obj" if ($oldfunc eq "kzalloc"); + + if ($a1 =3D~ s/^sizeof\s*\S\(?([^\)]*)\)?$/$1/) { + my $cnt =3D statement_rawlines($stat); + my $herectx =3D get_stat_here($linenr, $cnt, $here); + + if (WARN("ALLOC_WITH_SIZEOF", + "Prefer $newfunc over $oldfunc with sizeof\n" . $herectx) && + $cnt =3D=3D 1 && + $fix) { + $fixed[$fixlinenr] =3D~ s/\b($Lval)\s*\=3D\s*(?:$balanced_parens)?\s*= ((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*,/$1 =3D $newfunc($a1,/; + } + } + } + + +# check for (kv|k)[mz]alloc with multiplies that could be kmalloc_objs/kvm= alloc_objs/kzalloc_objs/kvzalloc_objs if ($perl_version_ok && defined $stat && $stat =3D~ /^\+\s*($Lval)\s*\=3D\s*(?:$balanced_parens)?\s*((?:kv|k)= [mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { my $oldfunc =3D $3; my $a1 =3D $4; my $a2 =3D $10; - my $newfunc =3D "kmalloc_array"; - $newfunc =3D "kvmalloc_array" if ($oldfunc eq "kvmalloc"); - $newfunc =3D "kvcalloc" if ($oldfunc eq "kvzalloc"); - $newfunc =3D "kcalloc" if ($oldfunc eq "kzalloc"); + my $newfunc =3D "kmalloc_objs"; + $newfunc =3D "kvmalloc_objs" if ($oldfunc eq "kvmalloc"); + $newfunc =3D "kvzalloc_objs" if ($oldfunc eq "kvzalloc"); + $newfunc =3D "kzalloc_objs" if ($oldfunc eq "kzalloc"); my $r1 =3D $a1; my $r2 =3D $a2; if ($a1 =3D~ /^sizeof\s*\S/) { @@ -7284,7 +7309,9 @@ sub process { "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && $cnt =3D=3D 1 && $fix) { - $fixed[$fixlinenr] =3D~ s/\b($Lval)\s*\=3D\s*(?:$balanced_parens)?\s*= ((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' =3D ' . "$ne= wfunc(" . trim($r1) . ', ' . trim($r2)/e; + my $sized =3D trim($r2); + $sized =3D~ s/^sizeof\s*\S\(?([^\)]*)\)?$/$1/; + $fixed[$fixlinenr] =3D~ s/\b($Lval)\s*\=3D\s*(?:$balanced_parens)?\s*= ((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' =3D ' . "$ne= wfunc(" . $sized . ', ' . trim($r1)/e; } } } --=20 2.34.1 From nobody Fri Dec 19 19:23:34 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 72BAA2EB86A; Wed, 3 Dec 2025 23:30:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764804637; cv=none; b=lgrwhlQVOiakCzImybHAduntnKHAbGJAsIe39GLBzKOgg+pNgJmo0QOO4qJ6IxlU2/6S1motED7MESbhwNDjiVdQ9yOjrv7FfdLvxFG0UBDaO775MPitQmQRfTp65ctTSOZ0P+pp1jxpN5dVI5Nm3swzIj59pF8LcoNkq1Ns1rU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764804637; c=relaxed/simple; bh=MfXbJ6vSs1Dx3b2SfnaSAfowCKIWsMTNjHXn3OinNe8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ricgTHyj797pMyE13q77RzMZNILzEPosTA87MbvrA9P9LfSGbWEs+wjEt7dfuKxdNr8pUKJ2Hhxr6foLCBMfAxgLMWgFSxBkEUZgKpU5MFeR0QvrwBjXsmkmg54N8IghGRsukkAs8ntvslDB2hZNr2dWkk/ABr5m5Ge7U9aYCu0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GkKzzvC5; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GkKzzvC5" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1E903C116C6; Wed, 3 Dec 2025 23:30:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764804637; bh=MfXbJ6vSs1Dx3b2SfnaSAfowCKIWsMTNjHXn3OinNe8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GkKzzvC57I+ubbzzUXskQZPPGE1GvWjqTiM3d35YfztkY9NIikn9kZ0T5XWf2PxAi GQ6P4Y3Spf4QUlTwHZJooN9f2Ia6Q2b9h0klqmRNW5/klLd0GuZR3Nu6FoApw+Xin1 DvbMZp62pbv1KK5jklUVk5wCy9maWxe2Ssb9xo8aqvEXedQVjo3AmEi19cUH/8ALvT Ygp8GmIrVwPmd692LyrycPTdMK6sBy7bIJxNyqc1f0HcrNv8hp8db+TRYQ9VUoU0AQ qHTcsbtd2ymA2lZ2RdBNlLW+UAD4OTaUBYSWACqvTKz3jPGGk8+ZcV++UUULCi9FaE e+CZ4JNFFVAxw== 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, Linus Torvalds , Randy Dunlap , Matthew Wilcox , John Hubbard , Joe Perches , Christoph Lameter , Vegard Nossum , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Roman Gushchin , Harry Yoo , Bill Wendling , Justin Stitt , Jann Horn , Greg Kroah-Hartman , Sasha Levin , linux-mm@kvack.org, Nick Desaulniers , Jonathan Corbet , Jakub Kicinski , Yafang Shao , Tony Ambardar , Alexander Lobakin , Jan Hendrik Farr , Alexander Potapenko , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, llvm@lists.linux.dev Subject: [PATCH v6 3/5] compiler_types: Introduce __flex_counter() and family Date: Wed, 3 Dec 2025 15:30:33 -0800 Message-Id: <20251203233036.3212363-3-kees@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251203233029.it.641-kees@kernel.org> References: <20251203233029.it.641-kees@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5281; i=kees@kernel.org; h=from:subject; bh=MfXbJ6vSs1Dx3b2SfnaSAfowCKIWsMTNjHXn3OinNe8=; b=owGbwMvMwCVmps19z/KJym7G02pJDJkGJ6SyquI9VTrT7K0fRN96M/XBg4q2dqVNr7rUPzbWO P1O3Leto5SFQYyLQVZMkSXIzj3OxeNte7j7XEWYOaxMIEMYuDgFYCLe/Qz/M962TshlVb25WTQ3 YnViltHfjsB5KdXZGiIu2ROm6jhNY2R4Op1R/sq13++vuB0wmvLk3Fpvj8u+a03qGFTK09OCWHb zAgA= X-Developer-Key: i=kees@kernel.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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(), overflows_flex_counter_type(), 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".) overflows_flex_counter_type(typeof(*p), array, COUNT) is the same as: COUNT <=3D type_max(p->counter) && COUNT >=3D 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 =3D 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 | 42 ++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index c46855162a8a..a31fe3dbf576 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -507,6 +507,37 @@ struct ftrace_likely_data { #define __annotated(var, attr) __builtin_has_attribute(var, attr) #endif =20 +/* + * Optional: only supported since gcc >=3D 15, clang >=3D 19 + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_00= 5f_005fbuiltin_005fcounted_005fby_005fref + * clang: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-coun= ted-by-ref + */ +#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_b= y() + * @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 725f95f7e416..f362e155a7ec 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -540,4 +540,46 @@ static inline size_t __must_check size_sub(size_t minu= end, size_t subtrahend) (__member_size((name)->array) / sizeof(*(name)->array) + \ __must_be_array((name)->array)) =20 +/** + * typeof_flex_counter() - Return the type of the counter variable of a gi= ven + * flexible array member annotated by __counted_by= (). + * @FAM: Instance of 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))) + +/** + * overflows_flex_counter_type() - Check if the counter associated with the + * given flexible array member can represent + * a value. + * @TYPE: Type of the struct that contains the @FAM. + * @FAM: Member name of the FAM within @TYPE. + * @COUNT: Value to check against the __counted_by annotated @FAM's counte= r. + * + * Returns: true if @COUNT can be represented in the @FAM's counter. When + * @FAM is not annotated with __counted_by(), always returns true. + */ +#define overflows_flex_counter_type(TYPE, FAM, COUNT) \ + (!overflows_type(COUNT, typeof_flex_counter(((TYPE *)NULL)->FAM))) + +/** + * __set_flex_counter() - Set the counter associated with the given flexib= le + * array member that has been annoated by __counted= _by(). + * @FAM: Instance of flexible array member within a given struct. + * @COUNT: Value to store to the __counted_by annotated @FAM_PTR's counter. + * + * This is a no-op if no annotation exists. Count needs to be checked with + * overflows_flex_counter_type() before using this function. + */ +#define __set_flex_counter(FAM, COUNT) \ +({ \ + *_Generic(__flex_counter(FAM), \ + void *: &(size_t){ 0 }, \ + default: __flex_counter(FAM)) =3D (COUNT); \ +}) + #endif /* __LINUX_OVERFLOW_H */ --=20 2.34.1 From nobody Fri Dec 19 19:23:34 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7B79B2EB87B; Wed, 3 Dec 2025 23:30:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764804637; cv=none; b=g2+cMtoMK/lyiYpveHSMtdkDf1VMrRfpKA4/iBapJk9mq4bag+FCWrfuS3A0zyuyYKH8hZXkEoiXwdvoB2juzdAtv4LewnZNtXgu0d5Ox7UNm3m8VKDvi/RDo4JULCb50I9PXGsoXWGDb9T6qweB5ys8dC3zgSbdGUNmKb9KGnY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764804637; c=relaxed/simple; bh=/3oEfKp5bU/+SWlxMLCCWi/qv6HDY8MmV0RMn5cIJmw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=PLs86OB0KRVzKVAc901T2tku1HKRdWJWRpDYsz35W23P8b3mtvTRNVD1dNmyyfzvyTGbEkWZdX4fnDLujsfmXuKeuz+QK8CkRkYtKEcj4paH6CsadZrZgmPSvSJGE58HYS6h/lQwuY0JS6jBPXoemb1AFyr9y3R1W7MM5aRarmE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QdDp1s8C; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QdDp1s8C" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 30DBEC2BCB2; Wed, 3 Dec 2025 23:30:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764804637; bh=/3oEfKp5bU/+SWlxMLCCWi/qv6HDY8MmV0RMn5cIJmw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QdDp1s8CleK4hn41r/2RClG5pRP24c3+GUC2GorVnlaRiJkA+OO5i3A0z+CAyKZ0Q dG0gZzAzwJFADJPJ53r65BfarPkFk1HJq9+WX8GHmuhrmPtZZ70HSbAKWlCrWqd+tK A8eJdl9ouGG1RD2Plye9Fj4BbMJNDMFIWDJ+U/vyWcG0RErdZ1/uj6bfAoEQ+uzVHZ qv3xUYM8tlNoRM7f3sZ29ueuvPbH+lxrzBPFV9RsRea/n/9+V3EYFbOWRz1Wk0jyRL A52Og2BDbN7t/zU1B4M8VCbaxeTVh7D5TtyXtNScg0JKvYKGhHi5Y3d+OMF/D4lgeO 5hUSu6sPYr1GA== From: Kees Cook To: Vlastimil Babka Cc: Kees Cook , Jonathan Corbet , Andrew Morton , Christoph Lameter , David Rientjes , Roman Gushchin , Harry Yoo , "Gustavo A. R. Silva" , workflows@vger.kernel.org, linux-doc@vger.kernel.org, linux-mm@kvack.org, linux-hardening@vger.kernel.org, Linus Torvalds , Randy Dunlap , Miguel Ojeda , Przemek Kitszel , Matthew Wilcox , John Hubbard , Joe Perches , Christoph Lameter , Marco Elver , Vegard Nossum , Pekka Enberg , Joonsoo Kim , Bill Wendling , Justin Stitt , Jann Horn , Greg Kroah-Hartman , Sasha Levin , Nathan Chancellor , Peter Zijlstra , Nick Desaulniers , Jakub Kicinski , Yafang Shao , Tony Ambardar , Alexander Lobakin , Jan Hendrik Farr , Alexander Potapenko , linux-kernel@vger.kernel.org, llvm@lists.linux.dev Subject: [PATCH v6 4/5] slab: Introduce kmalloc_flex() and family Date: Wed, 3 Dec 2025 15:30:34 -0800 Message-Id: <20251203233036.3212363-4-kees@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251203233029.it.641-kees@kernel.org> References: <20251203233029.it.641-kees@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7374; i=kees@kernel.org; h=from:subject; bh=/3oEfKp5bU/+SWlxMLCCWi/qv6HDY8MmV0RMn5cIJmw=; b=owGbwMvMwCVmps19z/KJym7G02pJDJkGJ6TKdwfPPHTuSsniQ00Mj6pWurkzsn85a/0uzETQn uPgkx1hHaUsDGJcDLJiiixBdu5xLh5v28Pd5yrCzGFlAhnCwMUpABOJU2Jk+KHcPLc3LHhHPr+l vjW/yYcIiz9m39hdXxyZNddfTuV9NCPD0vlfvwUqCsoHBT15EVrWv8Lyz9ulQnNSdlxrfZh8qdG IHQA= X-Developer-Key: i=kees@kernel.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" As done for kmalloc_obj*(), introduce a type-aware allocator for flexible arrays, which may also have "counted_by" annotations: ptr =3D kmalloc(struct_size(ptr, flex_member, count), gfp); becomes: ptr =3D kmalloc_flex(*ptr, flex_member, count, gfp); The internal use of __flex_counter() allows for automatically setting the counter member of a struct's flexible array member when it has been annotated with __counted_by(), avoiding any missed early size initializations while __counted_by() annotations are added to the kernel. Additionally, this also checks for "too large" allocations based on the type size of the counter variable. For example: if (count > type_max(ptr->flex_counter)) fail...; size =3D struct_size(ptr, flex_member, count); ptr =3D kmalloc(size, gfp); ptr->flex_counter =3D count; becomes (n.b. unchanged from earlier example): ptr =3D kmalloc_flex(*ptr, flex_member, count, gfp); ptr->flex_count =3D count; Note that manual initialization of the flexible array counter is still required (at some point) after allocation as not all compiler versions support the __counted_by annotation yet. But doing it internally makes sure they cannot be missed when __counted_by _is_ available, meaning that the bounds checker will not trip due to the lack of "early enough" initializations that used to work before enabling the stricter bounds checking. For example: ptr =3D kmalloc_flex(*ptr, flex_member, count, gfp); fill(ptr->flex, count); ptr->flex_count =3D count; This works correctly before adding a __counted_by annotation (since nothing is checking ptr->flex accesses against ptr->flex_count). After adding the annotation, the bounds sanitizer would trip during fill() because ptr->flex_count wasn't set yet. But with kmalloc_flex() setting ptr->flex_count internally at allocation time, the existing code works without needing to move the ptr->flex_count assignment before the call to fill(). (This has been a stumbling block for __counted_by adoption.) Signed-off-by: Kees Cook --- Cc: Jonathan Corbet Cc: Vlastimil Babka Cc: Andrew Morton Cc: Christoph Lameter Cc: David Rientjes Cc: Roman Gushchin Cc: Harry Yoo Cc: "Gustavo A. R. Silva" Cc: Cc: Cc: Cc: --- Documentation/process/deprecated.rst | 7 ++++ include/linux/slab.h | 48 ++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/Documentation/process/deprecated.rst b/Documentation/process/d= eprecated.rst index 91c628fa2d59..fed56864d036 100644 --- a/Documentation/process/deprecated.rst +++ b/Documentation/process/deprecated.rst @@ -387,6 +387,7 @@ allocations. For example, these open coded assignments:: ptr =3D kzalloc(sizeof(*ptr), gfp); ptr =3D kmalloc_array(count, sizeof(*ptr), gfp); ptr =3D kcalloc(count, sizeof(*ptr), gfp); + ptr =3D kmalloc(struct_size(ptr, flex_member, count), gfp); ptr =3D kmalloc(sizeof(struct foo, gfp); =20 become, respectively:: @@ -395,4 +396,10 @@ become, respectively:: ptr =3D kzalloc_obj(*ptr, gfp); ptr =3D kmalloc_objs(*ptr, count, gfp); ptr =3D kzalloc_objs(*ptr, count, gfp); + ptr =3D kmalloc_flex(*ptr, flex_member, count, gfp); __auto_type ptr =3D kmalloc_obj(struct foo, gfp); + +If `ptr->flex_member` is annotated with __counted_by(), the allocation +will automatically fail if `count` is larger than the maximum +representable value that can be stored in the counter member associated +with `flex_member`. diff --git a/include/linux/slab.h b/include/linux/slab.h index 726457daedbd..2656ea610b68 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -982,6 +982,33 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_fla= gs, int node); (TYPE *)KMALLOC(__obj_size, GFP); \ }) =20 +/** + * __alloc_flex - Allocate an object that has a trailing flexible array + * @KMALLOC: kmalloc wrapper function to use for allocation. + * @GFP: GFP flags for the allocation. + * @TYPE: type of structure to allocate space for. + * @FAM: The name of the flexible array member of @TYPE structure. + * @COUNT: how many @FAM elements to allocate space for. + * + * Returns: Newly allocated pointer to @TYPE with @COUNT-many trailing + * @FAM elements, or NULL on failure or if @COUNT cannot be represented + * by the member of @TYPE that counts the @FAM elements (annotated via + * __counted_by()). + */ +#define __alloc_flex(KMALLOC, GFP, TYPE, FAM, COUNT) \ +({ \ + const size_t __count =3D (COUNT); \ + const size_t __obj_size =3D struct_size_t(TYPE, FAM, __count); \ + TYPE *__obj_ptr; \ + if (WARN_ON_ONCE(overflows_flex_counter_type(TYPE, FAM, __count))) \ + __obj_ptr =3D NULL; \ + else \ + __obj_ptr =3D KMALLOC(__obj_size, GFP); \ + if (__obj_ptr) \ + __set_flex_counter(__obj_ptr->FAM, __count); \ + __obj_ptr; \ +}) + /** * kmalloc_obj - Allocate a single instance of the given type * @VAR_OR_TYPE: Variable or type to allocate. @@ -1005,23 +1032,44 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_= flags, int node); #define kmalloc_objs(VAR_OR_TYPE, COUNT, GFP) \ __alloc_objs(kmalloc, GFP, typeof(VAR_OR_TYPE), COUNT) =20 +/** + * kmalloc_flex - Allocate a single instance of the given flexible structu= re + * @VAR_OR_TYPE: Variable or type to allocate (with its flex array). + * @FAM: The name of the flexible array member of the structure. + * @COUNT: How many flexible array member elements are desired. + * @GFP: GFP flags for the allocation. + * + * Returns: newly allocated pointer to @VAR_OR_TYPE on success, NULL on + * failure. If @FAM has been annotated with __counted_by(), the allocation + * will immediately fail if @COUNT is larger than what the type of the + * struct's counter variable can represent. + */ +#define kmalloc_flex(VAR_OR_TYPE, FAM, COUNT, GFP) \ + __alloc_flex(kmalloc, GFP, typeof(VAR_OR_TYPE), FAM, COUNT) + /* All kzalloc aliases for kmalloc_(obj|objs|flex). */ #define kzalloc_obj(P, GFP) \ __alloc_objs(kzalloc, GFP, typeof(P), 1) #define kzalloc_objs(P, COUNT, GFP) \ __alloc_objs(kzalloc, GFP, typeof(P), COUNT) +#define kzalloc_flex(P, FAM, COUNT, GFP) \ + __alloc_flex(kzalloc, GFP, typeof(P), FAM, COUNT) =20 /* All kvmalloc aliases for kmalloc_(obj|objs|flex). */ #define kvmalloc_obj(P, GFP) \ __alloc_objs(kvmalloc, GFP, typeof(P), 1) #define kvmalloc_objs(P, COUNT, GFP) \ __alloc_objs(kvmalloc, GFP, typeof(P), COUNT) +#define kvmalloc_flex(P, FAM, COUNT, GFP) \ + __alloc_flex(kvmalloc, GFP, typeof(P), FAM, COUNT) =20 /* All kvzalloc aliases for kmalloc_(obj|objs|flex). */ #define kvzalloc_obj(P, GFP) \ __alloc_objs(kvzalloc, GFP, typeof(P), 1) #define kvzalloc_objs(P, COUNT, GFP) \ __alloc_objs(kvzalloc, GFP, typeof(P), COUNT) +#define kvzalloc_flex(P, FAM, COUNT, GFP) \ + __alloc_flex(kvzalloc, GFP, typeof(P), FAM, COUNT) =20 #define kmem_buckets_alloc(_b, _size, _flags) \ alloc_hooks(__kmalloc_node_noprof(PASS_BUCKET_PARAMS(_size, _b), _flags, = NUMA_NO_NODE)) --=20 2.34.1 From nobody Fri Dec 19 19:23:34 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AE1EB2FE045; Wed, 3 Dec 2025 23:30:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764804637; cv=none; b=tjQjEKBaBUljHmRHq5lNnArW8XSGgmHhL5moahi7hX9jkWw5FdmspZf59XfGupUwbToLao0WtsYWkJR1Vx+8zrM3EqwzybVL8WCkje/iPdJlMkfFCfQdXBO0eslpX8Kca3ObOAw+5akZc+V3qNQkHzZAGGDWEum1R0H2MBNn7PM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764804637; c=relaxed/simple; bh=5dAQ4T//TVYvlDNMsV5Y6TSBwmCOXpo3qNaO4v8qX0A=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=hzNzNBCtK3GhHCTszc9xgjPsOg45P9kRgKTCLC+EWzYDXuN7dH0053z6TJnEbI7zoN+OK6MgzRR8lvZ3Riz0bOIfl2S1tyfdkGvqNPsWwmaldsRd92QMrC1fAj0l2Xjp2Y7XbrAU3xFUUr5a5b+P5+4LJ6Bq2lw08X5xpJqMS68= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Tb1QFnmr; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Tb1QFnmr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5515AC2BCB9; Wed, 3 Dec 2025 23:30:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764804637; bh=5dAQ4T//TVYvlDNMsV5Y6TSBwmCOXpo3qNaO4v8qX0A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Tb1QFnmrmnR+zXH4fFBLmyxgcqpG4u3ZvwA7jcak8tIqWFqIsmYPPKVxGdTX8Ryvr R1Li+pHJWV1tAMBLLP3p+jTOEuYTJC+rO7oIZ4ejDqA1hne6lUoKesO8t7wxq6qoqz dGwtzcdHfbeL7AZLleyooLz5rSKKZZHmqOqNQT/gL2IqbrPdi1OGOn1CFy4tmYloBK ZP+6uTtqVaFhxeXwW8PA0tVDOwqLxJ/ruN46Fnaai8RPGeamw7sRh3iri3PFyf7QuU aqmZoLMDLVciN4vCgG365BnxUxt6oAmlIlK001XgapbBRngGvP07yXaJrao1Bu0yB+ aS4CkB0gAXGhg== From: Kees Cook To: Vlastimil Babka Cc: Kees Cook , Julia Lawall , Nicolas Palix , cocci@inria.fr, Linus Torvalds , Randy Dunlap , Miguel Ojeda , Przemek Kitszel , "Gustavo A. R. Silva" , Matthew Wilcox , John Hubbard , Joe Perches , Christoph Lameter , Marco Elver , Vegard Nossum , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Roman Gushchin , Harry Yoo , Bill Wendling , Justin Stitt , Jann Horn , Greg Kroah-Hartman , Sasha Levin , linux-mm@kvack.org, Nathan Chancellor , Peter Zijlstra , Nick Desaulniers , Jonathan Corbet , Jakub Kicinski , Yafang Shao , Tony Ambardar , Alexander Lobakin , Jan Hendrik Farr , Alexander Potapenko , linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, linux-doc@vger.kernel.org, llvm@lists.linux.dev Subject: [PATCH v6 5/5] coccinelle: Add kmalloc_objs conversion script Date: Wed, 3 Dec 2025 15:30:35 -0800 Message-Id: <20251203233036.3212363-5-kees@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251203233029.it.641-kees@kernel.org> References: <20251203233029.it.641-kees@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3968; i=kees@kernel.org; h=from:subject; bh=5dAQ4T//TVYvlDNMsV5Y6TSBwmCOXpo3qNaO4v8qX0A=; b=owGbwMvMwCVmps19z/KJym7G02pJDJkGJ6Sy9r13X/2Re2em+HFHS6vbrLaGdziDJu7dxrh1l R1vmPW3jlIWBjEuBlkxRZYgO/c4F4+37eHucxVh5rAygQxh4OIUgIl4hzD8L6ve9u7a1VXb7Pz5 MjPFYksnmr7e9rF9fq7z04VTjtk3ejH84bQ9zWIc4xC+xfH9mXsPlN8nHDdq3WiycYLhz4VWbE2 qDAA= X-Developer-Key: i=kees@kernel.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Finds and converts sized kmalloc-family of allocations into the typed kmalloc_obj-family of allocations. Signed-off-by: Kees Cook --- Cc: Julia Lawall Cc: Nicolas Palix Cc: cocci@inria.fr --- scripts/coccinelle/api/kmalloc_objs.cocci | 109 ++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 scripts/coccinelle/api/kmalloc_objs.cocci diff --git a/scripts/coccinelle/api/kmalloc_objs.cocci b/scripts/coccinelle= /api/kmalloc_objs.cocci new file mode 100644 index 000000000000..916cc3a661b9 --- /dev/null +++ b/scripts/coccinelle/api/kmalloc_objs.cocci @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// Use kmalloc_obj family of macros for allocations +/// +// Confidence: High +// Options: --include-headers-for-types --all-includes --include-headers -= -keep-comments + +virtual patch + +@initialize:python@ +@@ +import sys + +def alloc_array(name): + func =3D "FAILED_RENAME" + if name =3D=3D "kmalloc_array": + func =3D "kmalloc_objs" + elif name =3D=3D "kvmalloc_array": + func =3D "kvmalloc_objs" + elif name =3D=3D "kcalloc": + func =3D "kzalloc_objs" + elif name =3D=3D "kvcalloc": + func =3D "kvzalloc_objs" + else: + print(f"Unknown transform for {name}", file=3Dsys.stderr) + return func + +// This excludes anything that is assigning to or from integral types or +// string literals. Everything else gets the sizeof() extracted for the +// kmalloc_obj() type/var argument. sizeof(void *) is also excluded because +// it will need case-by-case double-checking to make sure the right type is +// being assigned. +@direct depends on patch && !(file in "tools") && !(file in "samples")@ +typedef u8, u16, u32, u64; +typedef __u8, __u16, __u32, __u64; +typedef uint8_t, uint16_t, uint32_t, uint64_t; +typedef __le16, __le32, __le64; +typedef __be16, __be32, __be64; +type INTEGRAL =3D {u8,__u8,uint8_t,char,unsigned char, + u16,__u16,uint16_t,unsigned short, + u32,__u32,uint32_t,unsigned int, + u64,__u64,uint64_t,unsigned long, + __le16,__le32,__le64,__be16,__be32,__be64}; +char [] STRING; +INTEGRAL *BYTES; +type TYPE; +expression VAR; +expression GFP; +expression COUNT; +expression FLEX; +expression E; +identifier ALLOC =3D~ "^kv?[mz]alloc$"; +fresh identifier ALLOC_OBJ =3D ALLOC ## "_obj"; +fresh identifier ALLOC_FLEX =3D ALLOC ## "_flex"; +identifier ALLOC_ARRAY =3D {kmalloc_array,kvmalloc_array,kcalloc,kvcalloc}; +fresh identifier ALLOC_OBJS =3D script:python(ALLOC_ARRAY) { alloc_array(A= LLOC_ARRAY) }; +@@ + +( +- VAR =3D ALLOC((sizeof(*VAR)), GFP) ++ VAR =3D ALLOC_OBJ(*VAR, GFP) +| + ALLOC((\(sizeof(STRING)\|sizeof(INTEGRAL)\|sizeof(INTEGRAL *)\)), GFP) +| + BYTES =3D ALLOC((sizeof(E)), GFP) +| + BYTES =3D ALLOC((sizeof(TYPE)), GFP) +| + ALLOC((sizeof(void *)), GFP) +| +- ALLOC((sizeof(E)), GFP) ++ ALLOC_OBJ(E, GFP) +| +- ALLOC((sizeof(TYPE)), GFP) ++ ALLOC_OBJ(TYPE, GFP) +| + ALLOC_ARRAY(COUNT, (\(sizeof(STRING)\|sizeof(INTEGRAL)\|sizeof(INTEGRAL *= )\)), GFP) +| + BYTES =3D ALLOC_ARRAY(COUNT, (sizeof(E)), GFP) +| + BYTES =3D ALLOC_ARRAY(COUNT, (sizeof(TYPE)), GFP) +| + ALLOC_ARRAY((\(sizeof(STRING)\|sizeof(INTEGRAL)\|sizeof(INTEGRAL *)\)), C= OUNT, GFP) +| + BYTES =3D ALLOC_ARRAY((sizeof(E)), COUNT, GFP) +| + BYTES =3D ALLOC_ARRAY((sizeof(TYPE)), COUNT, GFP) +| + ALLOC_ARRAY(COUNT, (sizeof(void *)), GFP) +| + ALLOC_ARRAY((sizeof(void *)), COUNT, GFP) +| +- ALLOC_ARRAY(COUNT, (sizeof(E)), GFP) ++ ALLOC_OBJS(E, COUNT, GFP) +| +- ALLOC_ARRAY(COUNT, (sizeof(TYPE)), GFP) ++ ALLOC_OBJS(TYPE, COUNT, GFP) +| +- ALLOC_ARRAY((sizeof(E)), COUNT, GFP) ++ ALLOC_OBJS(E, COUNT, GFP) +| +- ALLOC_ARRAY((sizeof(TYPE)), COUNT, GFP) ++ ALLOC_OBJS(TYPE, COUNT, GFP) +| +- ALLOC(struct_size(VAR, FLEX, COUNT), GFP) ++ ALLOC_FLEX(*VAR, FLEX, COUNT, GFP) +| +- ALLOC(struct_size_t(TYPE, FLEX, COUNT), GFP) ++ ALLOC_FLEX(TYPE, FLEX, COUNT, GFP) +) --=20 2.34.1