linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Kees Cook <kees@kernel.org>
To: Vlastimil Babka <vbabka@suse.cz>
Cc: Kees Cook <kees@kernel.org>, Christoph Lameter <cl@linux.com>,
	Pekka Enberg <penberg@kernel.org>,
	David Rientjes <rientjes@google.com>,
	Joonsoo Kim <iamjoonsoo.kim@lge.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Roman Gushchin <roman.gushchin@linux.dev>,
	Hyeonggon Yoo <42.hyeyoo@gmail.com>,
	linux-mm@kvack.org, Jann Horn <jannh@google.com>,
	Tony Luck <tony.luck@intel.com>,
	Nick Desaulniers <ndesaulniers@google.com>,
	Miguel Ojeda <ojeda@kernel.org>, Marco Elver <elver@google.com>,
	Nathan Chancellor <nathan@kernel.org>,
	Hao Luo <haoluo@google.com>,
	Przemek Kitszel <przemyslaw.kitszel@intel.com>,
	"Guilherme G. Piccoli" <gpiccoli@igalia.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Jakub Kicinski <kuba@kernel.org>,
	Petr Pavlu <petr.pavlu@suse.com>,
	Alexander Lobakin <aleksander.lobakin@intel.com>,
	Tony Ambardar <tony.ambardar@gmail.com>,
	linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org
Subject: [RFC][PATCH 3/4] slab: Allow for type introspection during allocation
Date: Mon,  8 Jul 2024 12:18:37 -0700	[thread overview]
Message-ID: <20240708191840.335463-3-kees@kernel.org> (raw)
In-Reply-To: <20240708190924.work.846-kees@kernel.org>

There is currently no way for the slab to know what type is being
allocated, and this hampers the development of any logic that would need
this information including basic type checking, alignment need analysis,
etc.

Allow the size argument to optionally be a variable, from which the
type (and there by the size, alignment, or any other features) can be
determined at compile-time. This allows for the incremental replacement
of the classic code pattern:

	obj = kmalloc(sizeof(*obj), gfp);

into:

	obj = kmalloc(obj, gfp);

As an additional build-time safety feature, the return value of kmalloc()
also becomes typed so that the assignment and first argument cannot drift,
doing away with the other, more fragile, classic code pattern:

	obj = kmalloc(sizeof(struct the_object), gfp);

into:

	obj = kmalloc(obj, gfp);

And any accidental variable drift will not be masked by the traditional
default "void *" return value:

	obj = kmalloc(something_else, gfp);

error: assignment to 'struct the_object *' from incompatible pointer type 'struct foo *' [-Wincompatible-pointer-types]
   71 |     obj = kmalloc(something_else, gfp);
      |         ^

This also opens the door for a proposed heap hardening feature that
would randomize the starting offset of the allocated object within
its power-of-2 bucket. Without being able to introspect the type for
alignment needs, this can't be done safely (or cannot be done without
significant memory usage overhead). For example, a 132 byte structure
with an 8 byte alignment could be randomized into 15 locations within
the 256 byte bucket: (256 - 132) / 8.

Signed-off-by: Kees Cook <kees@kernel.org>
---
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com>
Cc: linux-mm@kvack.org
---
 include/linux/slab.h | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/linux/slab.h b/include/linux/slab.h
index 7353756cbec6..4a7350bbcfe7 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -685,6 +685,7 @@ static __always_inline __alloc_size(1) void *kmalloc_noprof(size_t size, gfp_t f
 	return __kmalloc_noprof(size, flags);
 }
 #define kmalloc_sized(...)			alloc_hooks(kmalloc_noprof(__VA_ARGS__))
+#define kmalloc_aligned(size, align, gfp)	alloc_hooks(kmalloc_noprof(size, gfp))
 
 #define __size_force_positive(x)				\
 	({							\
@@ -701,7 +702,10 @@ static __always_inline __alloc_size(1) void *kmalloc_noprof(size_t size, gfp_t f
 	signed char:    kmalloc_sized(__size_force_positive(p), gfp), \
 	signed short:   kmalloc_sized(__size_force_positive(p), gfp), \
 	signed int:     kmalloc_sized(__size_force_positive(p), gfp), \
-	signed long:    kmalloc_sized(__size_force_positive(p), gfp))
+	signed long:    kmalloc_sized(__size_force_positive(p), gfp), \
+	default:	(typeof(__force_ptr_expr(p)))kmalloc_aligned(  \
+				sizeof(*__force_ptr_expr(p)),	      \
+				__alignof__(*__force_ptr_expr(p)), gfp))
 
 #define kmem_buckets_alloc(_b, _size, _flags)	\
 	alloc_hooks(__kmalloc_node_noprof(PASS_BUCKET_PARAMS(_size, _b), _flags, NUMA_NO_NODE))
@@ -816,14 +820,11 @@ static inline __alloc_size(1, 2) void *kmalloc_array_node_noprof(size_t n, size_
 
 /**
  * kzalloc - allocate memory. The memory is set to zero.
- * @size: how many bytes of memory are required.
+ * @p: either a pointer to an object to be allocated or bytes of memory are required.
  * @flags: the type of memory to allocate (see kmalloc).
  */
-static inline __alloc_size(1) void *kzalloc_noprof(size_t size, gfp_t flags)
-{
-	return kmalloc_noprof(size, flags | __GFP_ZERO);
-}
-#define kzalloc(...)				alloc_hooks(kzalloc_noprof(__VA_ARGS__))
+#define kzalloc(_p, _flags)			kmalloc(_p, (_flags)|__GFP_ZERO)
+#define kzalloc_noprof(_size, _flags)		kmalloc_noprof(_size, (_flags)|__GFP_ZERO)
 #define kzalloc_node(_size, _flags, _node)	kmalloc_node(_size, (_flags)|__GFP_ZERO, _node)
 
 void *__kvmalloc_node_noprof(DECL_BUCKET_PARAMS(size, b), gfp_t flags, int node) __alloc_size(1);
-- 
2.34.1



  parent reply	other threads:[~2024-07-08 19:18 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-08 19:18 [RFC][PATCH 0/4] " Kees Cook
2024-07-08 19:18 ` [RFC][PATCH 1/4] compiler_types: Add integral/pointer type helper macros Kees Cook
2024-07-08 19:18 ` [RFC][PATCH 2/4] slab: Detect negative size values and saturate Kees Cook
2024-07-09  6:57   ` Przemek Kitszel
2024-07-09 16:09     ` Kees Cook
2024-07-08 19:18 ` Kees Cook [this message]
2024-07-08 19:18 ` [RFC][PATCH 4/4] pstore: Replace classic kmalloc code pattern with typed argument Kees Cook
2024-07-09  7:06   ` Przemek Kitszel
2024-07-09 16:32     ` Kees Cook
2024-07-09 16:57 ` [RFC][PATCH 0/4] slab: Allow for type introspection during allocation Roman Gushchin
2024-07-09 18:57   ` Kees Cook
2024-07-09 17:26 ` Christoph Lameter (Ampere)
2024-07-09 20:28   ` Kees Cook
2024-07-09 21:02     ` Marco Elver
2024-07-09 23:28       ` Kees Cook
2024-07-10  4:42         ` Przemek Kitszel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240708191840.335463-3-kees@kernel.org \
    --to=kees@kernel.org \
    --cc=42.hyeyoo@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=aleksander.lobakin@intel.com \
    --cc=cl@linux.com \
    --cc=elver@google.com \
    --cc=gpiccoli@igalia.com \
    --cc=haoluo@google.com \
    --cc=iamjoonsoo.kim@lge.com \
    --cc=jannh@google.com \
    --cc=kuba@kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mark.rutland@arm.com \
    --cc=nathan@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=ojeda@kernel.org \
    --cc=penberg@kernel.org \
    --cc=petr.pavlu@suse.com \
    --cc=przemyslaw.kitszel@intel.com \
    --cc=rientjes@google.com \
    --cc=roman.gushchin@linux.dev \
    --cc=tony.ambardar@gmail.com \
    --cc=tony.luck@intel.com \
    --cc=vbabka@suse.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox