On Fri, 15 May 2026 at 16:28, Pedro Falcato <[email protected]> wrote: > > On Mon, May 11, 2026 at 10:00:48PM +0200, Marco Elver wrote: > > Rework the general infrastructure around RANDOM_KMALLOC_CACHES into more > > flexible KMALLOC_PARTITION_CACHES, with the former being a partitioning > > mode of the latter. > > > > Introduce a new mode, KMALLOC_PARTITION_TYPED, which leverages a feature > > available in Clang 22 and later, called "allocation tokens" via > > __builtin_infer_alloc_token() [1]. Unlike KMALLOC_PARTITION_RANDOM > > (formerly RANDOM_KMALLOC_CACHES), this mode deterministically assigns a > > slab cache to an allocation of type T, regardless of allocation site. > > > > 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*. > > > > Clang's default token ID calculation is described as [1]: > > > > typehashpointersplit: This mode assigns a token ID based on the hash > > of the allocated type's name, where the top half ID-space is reserved > > for types that contain pointers and the bottom half for types that do > > not contain pointers. > > > > Separating pointer-containing objects from pointerless objects and data > > allocations can help mitigate certain classes of memory corruption > > exploits [2]: attackers who gains a buffer overflow on a primitive > > buffer cannot use it to directly corrupt pointers or other critical > > metadata in an object residing in a different, isolated heap region. > > > > It is important to note that heap isolation strategies offer a > > best-effort approach, and do not provide a 100% security guarantee, > > albeit achievable at relatively low performance cost. Note that this > > also does not prevent cross-cache attacks: while waiting for future > > features like SLAB_VIRTUAL [3] to provide physical page isolation, this > > feature should be deployed alongside SHUFFLE_PAGE_ALLOCATOR and > > init_on_free=1 to mitigate cross-cache attacks and page-reuse attacks as > > much as possible today. > > > > With all that, my kernel (x86 defconfig) shows me a histogram of slab > > cache object distribution per /proc/slabinfo (after boot): > > > > <slab cache> <objs> <hist> > > kmalloc-part-15 1465 ++++++++++++++ > > kmalloc-part-14 2988 +++++++++++++++++++++++++++++ > > kmalloc-part-13 1656 ++++++++++++++++ > > kmalloc-part-12 1045 ++++++++++ > > kmalloc-part-11 1697 ++++++++++++++++ > > kmalloc-part-10 1489 ++++++++++++++ > > kmalloc-part-09 965 +++++++++ > > kmalloc-part-08 710 +++++++ > > kmalloc-part-07 100 + > > kmalloc-part-06 217 ++ > > kmalloc-part-05 105 + > > kmalloc-part-04 4047 ++++++++++++++++++++++++++++++++++++++++ > > kmalloc-part-03 183 + > > kmalloc-part-02 283 ++ > > kmalloc-part-01 316 +++ > > kmalloc 1422 ++++++++++++++ > > Hi, > > A couple of questions (I apologise if this was asked before, I wasn't involved > in this thread): > > 1) What's the object behind kmalloc-part-04? I imagine it's a single type > getting allocated a lot?
That's from __kmemdup_nul(). > 2) The bucketing looks quite skewed. Do you have plans to implement something > more similar to what's in the original Apple blog post (with the smaller > granularity and all)? I'm asking because most of our types have pointers in > some way. Having a scheme more tailored towards kernel data structures would be nice. But we first need to build experience with this, and get more data. I think I agree with you that a smaller granularty scheme that tries to bucket similarly-shaped objects (e.g. with a pointer bitmap) will work better for the kernel, but I have no evidence of that yet. We need an analysis of "this scheme would have stopped X out of Y exploit chains". There are plans to look into that. But if an improvement comes out of it, it's just a compiler-flag flip away for the kernel, once the compiler supports it. There's also what Kees had proposed: https://lore.kernel.org/lkml/[email protected]/ .. but that trades memory and performance for stronger partitioning. Probably should become another KMALLOC_PARTITION variant. But if performance and memory usage are a concern (which is the case for environments where I'd like to enable this), we need a smarter token calculation scheme (if the current one is not good enough after some analysis). > 3) Obligatory "how about GCC?" :) I quite like the idea behind this feature, > and it would be awesome if it could be more broadly deployed! +cc linux-toolchains We'd need __builtin_infer_alloc_token + -falloc-token-max= for kernel support (-fsanitize=alloc-token is not needed if kernel support is all you'd care about): https://clang.llvm.org/docs/AllocToken.html#querying-token-ids-with-builtin-infer-alloc-token Thanks, -- Marco

