Re: [PATCH] mm/util: Use kmalloc buckets for kmemdup_nul()
From: Marco Elver
Date: Thu May 21 2026 - 08:56:34 EST
On Thu, 21 May 2026 at 14:40, Kees Cook <kees@xxxxxxxxxx> wrote:
>
> The use of the kmemdup_nul()-family of allocations are explicitly for
> allocating NUL terminated strings, so these would be best separated from
> typed allocations, as they are their own set of arbitrarily sized
> allocations. They are not as risky as userspace controlled allocations,
> but these would be good to separate as well.
>
> # grep memdup_nul /proc/slabinfo | cut -c-25
> memdup_nul-8k 0
> memdup_nul-4k 0
> memdup_nul-2k 0
> memdup_nul-1k 0
> memdup_nul-512 28
> memdup_nul-256 0
> memdup_nul-192 60
> memdup_nul-128 60
> memdup_nul-96 60
> memdup_nul-64 180
> memdup_nul-32 960
> memdup_nul-16 1860
> memdup_nul-8 1980
>
> Suggested-by: Harry Yoo <harry@xxxxxxxxxx>
> Signed-off-by: Kees Cook <kees@xxxxxxxxxx>
> ---
> Cc: Vlastimil Babka <vbabka@xxxxxxxxxx>
> Cc: Marco Elver <elver@xxxxxxxxxx>
> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
> Cc: David Hildenbrand <david@xxxxxxxxxx>
> Cc: Lorenzo Stoakes <ljs@xxxxxxxxxx>
> Cc: "Liam R. Howlett" <liam@xxxxxxxxxxxxx>
> Cc: Mike Rapoport <rppt@xxxxxxxxxx>
> Cc: Suren Baghdasaryan <surenb@xxxxxxxxxx>
> Cc: Michal Hocko <mhocko@xxxxxxxx>
> Cc: <linux-mm@xxxxxxxxx>
Acked-by: Marco Elver <elver@xxxxxxxxxx>
> ---
> mm/util.c | 12 +++++++-----
> 1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/mm/util.c b/mm/util.c
> index 3cc949a0b7ed..419269bb53da 100644
> --- a/mm/util.c
> +++ b/mm/util.c
> @@ -34,6 +34,9 @@
> #include "internal.h"
> #include "swap.h"
>
> +static kmem_buckets *user_buckets __ro_after_init;
> +static kmem_buckets *nul_buckets __ro_after_init;
> +
> /**
> * kfree_const - conditionally free memory
> * @x: pointer to the memory
> @@ -61,7 +64,7 @@ static __always_inline char *__kmemdup_nul(const char *s, size_t len, gfp_t gfp)
> char *buf;
>
> /* '+1' for the NUL terminator */
> - buf = kmalloc_track_caller(len + 1, gfp);
> + buf = kmem_buckets_alloc_track_caller(nul_buckets, len + 1, gfp);
> if (!buf)
> return NULL;
>
> @@ -195,15 +198,14 @@ char *kmemdup_nul(const char *s, size_t len, gfp_t gfp)
> }
> EXPORT_SYMBOL(kmemdup_nul);
>
> -static kmem_buckets *user_buckets __ro_after_init;
> -
> -static int __init init_user_buckets(void)
> +static int __init init_buckets(void)
> {
> user_buckets = kmem_buckets_create("memdup_user", 0, 0, INT_MAX, NULL);
> + nul_buckets = kmem_buckets_create("memdup_nul", 0, 0, INT_MAX, NULL);
>
> return 0;
> }
> -subsys_initcall(init_user_buckets);
> +subsys_initcall(init_buckets);
>
> /**
> * memdup_user - duplicate memory region from user space
> --
> 2.34.1
>