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/[email protected]/
[2] https://lore.kernel.org/lkml/[email protected]/

-- 
Kees Cook

Reply via email to