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

Harry Yoo (Oracle)
2026-04-07T12:54:28Z

On Tue, Apr 07, 2026 at 01:17:14PM +0200, Marco Elver wrote:
> On Mon, 6 Apr 2026 at 06:28, 'Harry Yoo (Oracle)' via kasan-dev
> <kasan-dev@googlegroups.com> wrote:
> > On Fri, Apr 03, 2026 at 08:29:22PM +0200, Vlastimil Babka (SUSE) wrote:
> > > On 4/3/26 08:27, Harry Yoo (Oracle) wrote:
> > > >> diff --git a/include/linux/slab.h b/include/linux/slab.h
> > > >> index 15a60b501b95..c0bf00ee6025 100644
> > > >> --- a/include/linux/slab.h
> > > >> +++ b/include/linux/slab.h
> > > >> @@ -864,10 +877,10 @@ unsigned int kmem_cache_sheaf_size(struct slab_sheaf *sheaf);
> > > >> * with the exception of kunit tests
> > > >> */
> > > >>
> > > >> -void *__kmalloc_noprof(size_t size, gfp_t flags)
> > > >> +void *__kmalloc_noprof(size_t size, gfp_t flags, kmalloc_token_t token)
> > > >> __assume_kmalloc_alignment __alloc_size(1);
> > > >>
> > > >> -void *__kmalloc_node_noprof(DECL_BUCKET_PARAMS(size, b), gfp_t flags, int node)
> > > >> +void *__kmalloc_node_noprof(DECL_BUCKET_PARAMS(size, b), gfp_t flags, int node, kmalloc_token_t token)
> > > >> __assume_kmalloc_alignment __alloc_size(1);
> > > >
> > > > So the @token parameter is unused when CONFIG_PARTITION_KMALLOC_CACHES is
> > > > disabled but still increases the kernel size by a few kilobytes...
> > > > but yeah I'm not sure if we can get avoid it without hurting readability.
> > > >
> > > > Just saying. (does anybody care?)
> > >
> > > Well we did care enough with CONFIG_SLAB_BUCKETS to hide the unused param
> > > using DECL_BUCKET_PARAMS(),
> >
> > Hmm yeah.
> >
> > I wasn't sure if we could do this without hurting readability,
> > but perhaps we could...
> >
> > > so maybe extend that idea?
> > > I think it's not just kernel size, but increased register pressure etc.
>
> I'll take a closer look at generated code.

> In some cases the compiler ought to omit zero-sized arguments,

Oh, didn't know that was a thing.

Not sure if it's safe to do that for exported functions though (since
modules can be built w/ a different compiler).

> so I want to be sure we're not
> prematurely optimizing and the size increase is not some other effect.

Great, thanks for looking into it.

> > Something like this should work? (diff on top of this patch)
>
> Thanks, I'll consider it.

Thanks.

> Re your other comments:
>
> > Assuming not all people building the kernel are security experts...
> > (including myself) could you please add some insights/guidance on how to
> > decide between RANDOM_KMALLOC_CACHES and TYPED_KMALLOC_CACHES?
>
> You can find different arguments for either, and in the original RFC
> that was part of the discussion.

Yeah, I had fun time following the discussions :)

> However, my biased view is that type-based partitioning in general
> is the stronger security boundary.
> Because it creates a deterministic separation; specifically isolating
> pointer-containing objects from pointerless ones: it effectively kills
> certain classes of exploit techniques that probabilistic defenses
> (like randomization) only delay, especially in environments where
> attackers can retry or use side-channels.

That's a fair argument.

Could we possibly put some of those arguments (in a neutral/technical
sense) in help text to make people's lives easier?

Err, trying to provide unbiased (tm) help text...
Something like:

config RANDOM_KMALLOC_CACHES
bool "Randomize slab caches for normal kmalloc"
help
Randomly pick a slab cache based on code address and a per-boot
random seed.

This makes it harder for attackers to predict object co-location.
The placement is random: while attackers don't know which kmalloc
cache an object will be allocated from, they might circumvent
the randomization by retrying attacks across multiple machines until
the target objects are co-located.

config TYPED_KMALLOC_CACHES
bool "Type based slab cache selection for normal kmalloc"
depends on $(cc-option,-falloc-token-max=123)
help
Rely on Clang's allocation tokens to choose a slab cache, where token
IDs are derived from the allocated type.

Unlike RANDOM_KMALLOC_CACHES, the cache assignment is deterministic
and based on type, which guarantees that objects of certain types
are not placed in the same cache. This effectively mitigates
certain classes of exploits that probabilistic defenses like
RANDOM_KMALLOC_CACHES only make harder but not impossible.
However, this also means the cache assignment is predictable.

For example, a token ID scheme might separate pointer-containing
objects and pointerless objects to prevent buffer overflows on
primitive buffers from directly corrupting pointer-containing objects.

The current effectiveness of Clang's type inference can be judged by
-Rpass=alloc-token, which provides diagnostics where (after dead-code
elimination) type inference failed.

Requires Clang 22 or later.

endchoice

> The current pointer/non-pointer scheme is relatively intuitive with
> well-understood properties, and a good start.
>
> However, an open research question is if better alloc-token ID schemes exist:
> one that is tailored to kernel data structures that would meaningfully
> increase exploitation difficulty further without increasing the number of
> partitions.

Haha, that's too adventurous research question for me :P

> Since an improved scheme could simply be activated with a
> compiler flag, having the baseline infrastructure available and
> maintained is the first step.

Agreed.

> > Now somewhat out-of-scope (or at least pre-existing) review comments
> > from Sashiko that I think are still worth mentioning...
>
> Indeed, these are pre-existing issues with RANDOM_KMALLOC_CACHES.
> Worth follow-up patches, but this patch here wants to just get the
> TYPED_KMALLOC_CACHES infrastructure in place so we can build on top of
> it.

Yeah, that's totally fine!