On Thu, 21 May 2026 at 14:40, Kees Cook <[email protected]> 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 <[email protected]>
> Signed-off-by: Kees Cook <[email protected]>
> ---
> Cc: Vlastimil Babka <[email protected]>
> Cc: Marco Elver <[email protected]>
> Cc: Andrew Morton <[email protected]>
> Cc: David Hildenbrand <[email protected]>
> Cc: Lorenzo Stoakes <[email protected]>
> Cc: "Liam R. Howlett" <[email protected]>
> Cc: Mike Rapoport <[email protected]>
> Cc: Suren Baghdasaryan <[email protected]>
> Cc: Michal Hocko <[email protected]>
> Cc: <[email protected]>

Acked-by: Marco Elver <[email protected]>

> ---
>  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
>

Reply via email to