Re: [PATCH v2] slab: support for compiler-assisted type-based slab cache partitioning

Kees Cook
2026-04-21T17:22:43Z

On Wed, Apr 15, 2026 at 04:37:05PM +0200, Marco Elver wrote:
> The builtin __builtin_infer_alloc_token(<malloc-args>, ...) instructs
> the compiler to infer an allocation type from arguments commonly passed
> to memory-allocating functions and returns a type-derived token ID. The
> implementation passes kmalloc-args to the builtin: the compiler performs
> best-effort type inference, and then recognizes common patterns such as
> `kmalloc(sizeof(T), ...)`, `kmalloc(sizeof(T) * n, ...)`, but also
> `(T *)kmalloc(...)`. Where the compiler fails to infer a type the
> fallback token (default: 0) is chosen.
>
> Note: kmalloc_obj(..) APIs fix the pattern how size and result type are
> expressed, and therefore ensures there's not much drift in which
> patterns the compiler needs to recognize. Specifically, kmalloc_obj()
> and friends expand to `(TYPE *)KMALLOC(__obj_size, GFP)`, which the
> compiler recognizes via the cast to TYPE*.

Great! I'm glad this gets deterministically handled for the kmalloc_obj*
cases.

> Additionally, when I compile my kernel with -Rpass=alloc-token, which
> provides diagnostics where (after dead-code elimination) type inference
> failed, I see 186 allocation sites where the compiler failed to identify
> a type (down from 966 when I sent the RFC [4]). Some initial review
> confirms these are mostly variable sized buffers, but also include
> structs with trailing flexible length arrays.

For the call-site-partitioning series[1] I sent before, I had
per-site caches for fixed-sized allocations and size bucket caches for
variably-sized allocations. I'd like to see something similar for this
series. Specifically, I replaced "kmalloc_slab" with "choose_slab" that
did O(1) to find the dedicated cache/bucket for the allocation[2].

In this case, we now have a build-time-constant value that it should be
possible to use to look up a _single_ dedicated cache/bucket for the
given unique type: there is no need to do hashing.

> [...]
> -config RANDOM_KMALLOC_CACHES
> - default n
> +config PARTITION_KMALLOC_CACHES
> depends on !SLUB_TINY
> - bool "Randomize slab caches for normal kmalloc"
> + bool "Partitioned slab caches for normal kmalloc"
> help
> - A hardening feature that creates multiple copies of slab caches for
> - normal kmalloc allocation and makes kmalloc randomly pick one based
> - on code address, which makes the attackers more difficult to spray
> - vulnerable memory objects on the heap for the purpose of exploiting
> - memory vulnerabilities.
> + A hardening feature that creates multiple isolated copies of slab
> + caches for normal kmalloc allocations. This makes it more difficult
> + to exploit memory-safety vulnerabilities by attacking vulnerable
> + co-located memory objects. Several modes are provided.
>
> Currently the number of copies is set to 16, a reasonably large value

The "16" buckets seems to hold for TYPED_KMALLOC_CACHES too? My goal
with the earlier type-partitioning was to get _total_ isolation, not
simply bucketed: 1 cache (or sizes-bucket) for each type. The "16"
limitation from RANDOM_KMALLOC_CACHES was kind of arbitrary due to the
hashing.

> that effectively diverges the memory objects allocated for different
> subsystems or modules into different caches, at the expense of a
> - limited degree of memory and CPU overhead that relates to hardware and
> - system workload.
> + limited degree of memory and CPU overhead that relates to hardware
> + and system workload.
> +
> +choice
> + prompt "Partitioned slab cache mode"
> + depends on PARTITION_KMALLOC_CACHES
> + default RANDOM_KMALLOC_CACHES

I think this should be adjusted a bit:

config CC_HAS_ALLOC_TOKEN
def_bool $(cc-option,-falloc-token-max=123)

...
choice
prompt "Partitioned slab cache mode"
depends on PARTITION_KMALLOC_CACHES
default TYPED_KMALLOC_CACHES if CC_HAS_ALLOC_TOKEN
default RANDOM_KMALLOC_CACHES

And actually, perhaps a global rename of the options so the selection
naming is at the end of the CONFIG phrase, and bundle the on/off into
the choice:

choice
prompt "Partitioned slab cache mode"
depends on PARTITION_KMALLOC_CACHES
default KMALLOC_PARTITION_TYPED if !SLUB_TINY && CC_HAS_ALLOC_TOKEN
default KMALLOC_PARTITION_RANDOM if !SLUB_TINY
default KMALLOC_PARTITION_NONE

config KMALLOC_PARTITION_NONE
...
config KMALLOC_PARTITION_RANDOM
depends on !SLUB_TINY
...
config KMALLOC_PARTITION_TYPED
depends on !SLUB_TINY && CC_HAS_ALLOC_TOKEN

-Kees

[1] https://lore.kernel.org/lkml/20240809072532.work.266-kees@kernel.org/
[2] https://lore.kernel.org/lkml/20240809073309.2134488-5-kees@kernel.org/

--
Kees Cook