SLUB Internals for Exploit Developers - Andrey Konovalov, xairy.io
Provides SLUB Internals for Exploit Developers - Andrey Konovalov, xairy.io and evaluates key implications for security practitioners.
Summary
### Overview In this talk, Andrey Konovalov explores the internal mechanics of the Linux kernel's SLUB allocator and explains how its architecture connects to heap/slab shaping techniques commonly used in kernel exploitation. Konovalov highlights a gap in existing literature, where exploitation write-ups often omit allocator internals, and allocator documentation overlooks practical exploitation mechanics. Targetting Linux kernel version 6.6 under default configurations (single NUMA node, single CPU focus, SLUB debug disabled), the presentation details the allocator's data structures, multi-tiered allocation and freeing algorithms, and practical heap-shaping strategies for out-of-bounds (OOB) and use-after-free (UAF) vulnerabilities.
### Key Topics - **SLUB Architecture & Data Structures:** The role of `kmalloc` caches (`struct km_cache`), per-CPU states (`struct km_cache_cpu`), NUMA node lists (`struct km_cache_node`), and physical page/slab tracking via `struct slab` / `struct page`. - **Metadata Security & Hardening:** How free lists link free slots, the mitigation moving free list pointers to the middle of the slot, pointer XOR hashing (using per-cache random values and slot addresses), and random free list order on new slabs. - **Allocation & Freeing Workflows:** Multi-tiered allocation hierarchy (lockless per-CPU list, per-slab list, per-CPU partial slabs, per-node partial slabs, and new slab allocation from the page allocator) and the freeing mechanics across active, non-active, and full slabs. - **Slab Shaping Strategies:** Methods for arranging vulnerable and target objects in memory for OOB and UAF scenarios, including plugging existing holes, spraying, and creating controlled holes across slabs. - **Reliability & Mitigation Challenges:** Real-world obstacles such as preemption, CPU migration, and upcoming kernel defenses (e.g., per-call-site caches, SLAB_VIRTUAL, and ARM MTE).
### Technical Details - **Free List Mechanics:** SLUB stores free list metadata directly inside free object slots. Modern kernels place this pointer near the middle of the slot (`address + object_size / 2` aligned to 8 bytes) and hash it with a per-cache random value and slot address, making pointer forgery difficult. Exploitation typically focuses on corrupting adjacent target objects rather than free list metadata. - **Slab Tracking Tiers:** 1. *Active Slab:* Serves current CPU allocations first; possesses two independent free lists—a lockless per-CPU free list and a per-slab locked free list (used when remote CPUs free an object belonging to this slab). 2. *Per-CPU Partial Slabs:* Linked singly, tracked up to a kernel threshold (`cpu_partial_slabs`). 3. *Per-Node Partial Slabs:* Linked doubly, maintained globally across CPUs with a minimum threshold (`min_partial`). 4. *Full Slabs:* Unlinked and untracked by the allocator until an object inside is freed, at which point `virt_to_slab` resolves the slab struct from page structs. - **Shaping for Out-of-Bounds (OOB):** - *Separate Alloc/Trigger:* Attackers estimate cache holes (e.g., via `/proc/slabinfo` after shrinking on a local environment), allocate target objects to fill existing holes and force a new active slab, allocate the vulnerable object, and fill the remainder with target objects (`objects_per_slab - 1`). - *Combined Alloc/Trigger (Allocation-Only):* If trigger happens immediately upon allocation, allocating without filling risks writing out-of-bounds into a free slot. Because free list pointers sit in the middle of slots, minor out-of-bounds writes often do not corrupt metadata or crash the kernel, allowing retries. - *Making Holes Approach:* Creates several full slabs of target objects (`objects_per_slab + 1`), frees one object from each to create partial slabs, and drains preceding slabs so the vulnerable object occupies the exact vacant slot followed by target objects. - **Shaping for Use-After-Free (UAF):** - *Active Slab UAF:* If an allocation and free directly cycle through the lockless free list, an immediate subsequent target allocation reliably claims the exact same slot. - *Deep Partial Slab Reclamation:* When an object is buried in a partial slab (such as when upgrading an OOB write to decrement a target object's reference counter), attackers spray target allocations to consume active slab holes and pull the desired slab forward.
### Takeaways - **Understanding Allocator State is Critical:** Reliable slab shaping relies on manipulating the allocator's five allocation tiers and list transitions (active -> per-CPU partial -> per-node partial). - **Exploitation Success is Non-Deterministic:** CPU migration (mitigated by setting affinity with `sched_setaffinity`), task preemption, and global per-node slab activity from other CPUs prevent 100% reliability. - **Evolving Mitigations:** While random free list ordering and pointer hashing deterred direct free list tampering, structural hardening such as separate per-subsystem/call-site caches, SLAB_VIRTUAL against cross-cache attacks, and hardware-based Memory Tagging Extensions (MTE) increasingly limit object-overwriting strategies.
Related talks
TROOPERS IT Security Conference·51 min
Emmanuel Law
Emmanuel Law analyzes TR17 - PHP Internals Exploit Dev Edition.
BSides Portland·43 min
Jarrod Overson
Presenters detail vulnerability discovery and exploitation in Jarrod Overson - How did 8 million developers download an exploit with no one noticing?.
The Linux Foundation·41 min
Hiroshi Hayakawa
Investigates architecting Kubernetes-Based Internal Developer Platforms: Essential Patterns and evaluates key implications for security practitioners.


