mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-08-09 06:14:34 +02:00
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 ++++++++++++++ The above /proc/slabinfo snapshot shows me there are 6673 allocated objects (slabs 00 - 07) that the compiler claims contain no pointers or it was unable to infer the type of, and 12015 objects that contain pointers (slabs 08 - 15). On a whole, this looks relatively sane. 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. Link: https://clang.llvm.org/docs/AllocToken.html [1] Link: https://blog.dfsec.com/ios/2025/05/30/blasting-past-ios-18/ [2] Link: https://lwn.net/Articles/944647/ [3] Link: https://lore.kernel.org/all/20250825154505.1558444-1-elver@google.com/ [4] Link: https://discourse.llvm.org/t/rfc-a-framework-for-allocator-partitioning-hints/87434 Acked-by: GONG Ruiqi <gongruiqi1@huawei.com> Co-developed-by: Harry Yoo (Oracle) <harry@kernel.org> Signed-off-by: Harry Yoo (Oracle) <harry@kernel.org> Signed-off-by: Marco Elver <elver@google.com> Reviewed-by: Harry Yoo (Oracle) <harry@kernel.org> Link: https://patch.msgid.link/20260511200136.3201646-1-elver@google.com Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
114 lines
3.3 KiB
Plaintext
114 lines
3.3 KiB
Plaintext
# Help: Basic kernel hardening options
|
|
#
|
|
# These are considered the basic kernel hardening, self-protection, and
|
|
# attack surface reduction options. They are expected to have low (or
|
|
# no) performance impact on most workloads, and have a reasonable level
|
|
# of legacy API removals.
|
|
|
|
# Make sure reporting of various hardening actions is possible.
|
|
CONFIG_BUG=y
|
|
|
|
# Basic kernel memory permission enforcement.
|
|
CONFIG_STRICT_KERNEL_RWX=y
|
|
CONFIG_STRICT_MODULE_RWX=y
|
|
CONFIG_VMAP_STACK=y
|
|
|
|
# Kernel image and memory ASLR.
|
|
CONFIG_RANDOMIZE_BASE=y
|
|
CONFIG_RANDOMIZE_MEMORY=y
|
|
|
|
# Randomize allocator freelists, harden metadata.
|
|
CONFIG_SLAB_FREELIST_RANDOM=y
|
|
CONFIG_SLAB_FREELIST_HARDENED=y
|
|
CONFIG_SLAB_BUCKETS=y
|
|
CONFIG_SHUFFLE_PAGE_ALLOCATOR=y
|
|
CONFIG_KMALLOC_PARTITION_CACHES=y
|
|
|
|
# Sanity check userspace page table mappings.
|
|
CONFIG_PAGE_TABLE_CHECK=y
|
|
CONFIG_PAGE_TABLE_CHECK_ENFORCED=y
|
|
|
|
# Randomize kernel stack offset on syscall entry.
|
|
CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y
|
|
|
|
# Basic stack frame overflow protection.
|
|
CONFIG_STACKPROTECTOR=y
|
|
CONFIG_STACKPROTECTOR_STRONG=y
|
|
|
|
# Basic buffer length bounds checking.
|
|
CONFIG_HARDENED_USERCOPY=y
|
|
CONFIG_FORTIFY_SOURCE=y
|
|
|
|
# Basic array index bounds checking.
|
|
CONFIG_UBSAN=y
|
|
CONFIG_UBSAN_TRAP=y
|
|
CONFIG_UBSAN_BOUNDS=y
|
|
# CONFIG_UBSAN_SHIFT is not set
|
|
# CONFIG_UBSAN_DIV_ZERO is not set
|
|
# CONFIG_UBSAN_UNREACHABLE is not set
|
|
# CONFIG_UBSAN_INTEGER_WRAP is not set
|
|
# CONFIG_UBSAN_BOOL is not set
|
|
# CONFIG_UBSAN_ENUM is not set
|
|
# CONFIG_UBSAN_ALIGNMENT is not set
|
|
|
|
# Sampling-based heap out-of-bounds and use-after-free detection.
|
|
CONFIG_KFENCE=y
|
|
|
|
# Linked list integrity checking.
|
|
CONFIG_LIST_HARDENED=y
|
|
|
|
# Initialize all heap variables to zero on allocation.
|
|
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
|
|
|
|
# Initialize all heap variables to zero on free to reduce stale data lifetime.
|
|
CONFIG_INIT_ON_FREE_DEFAULT_ON=y
|
|
|
|
# Initialize all stack variables to zero on function entry.
|
|
CONFIG_INIT_STACK_ALL_ZERO=y
|
|
|
|
# Wipe kernel stack after syscall completion to reduce stale data lifetime.
|
|
CONFIG_KSTACK_ERASE=y
|
|
|
|
# Wipe RAM at reboot via EFI. For more details, see:
|
|
# https://trustedcomputinggroup.org/resource/pc-client-work-group-platform-reset-attack-mitigation-specification/
|
|
# https://bugzilla.redhat.com/show_bug.cgi?id=1532058
|
|
CONFIG_RESET_ATTACK_MITIGATION=y
|
|
|
|
# Disable DMA between EFI hand-off and the kernel's IOMMU setup.
|
|
CONFIG_EFI_DISABLE_PCI_DMA=y
|
|
|
|
# Force IOMMU TLB invalidation so devices will never be able to access stale
|
|
# data content.
|
|
CONFIG_IOMMU_SUPPORT=y
|
|
CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
|
|
|
|
# Do not allow direct physical memory access to non-device memory.
|
|
CONFIG_STRICT_DEVMEM=y
|
|
CONFIG_IO_STRICT_DEVMEM=y
|
|
|
|
# Provide userspace with seccomp BPF API for syscall attack surface reduction.
|
|
CONFIG_SECCOMP=y
|
|
CONFIG_SECCOMP_FILTER=y
|
|
|
|
# Provides some protections against SYN flooding.
|
|
CONFIG_SYN_COOKIES=y
|
|
|
|
# Enable Kernel Control Flow Integrity.
|
|
CONFIG_CFI=y
|
|
# CONFIG_CFI_PERMISSIVE is not set
|
|
|
|
# Attack surface reduction: do not autoload TTY line disciplines.
|
|
# CONFIG_LDISC_AUTOLOAD is not set
|
|
|
|
# Dangerous; enabling this disables userspace brk ASLR.
|
|
# CONFIG_COMPAT_BRK is not set
|
|
|
|
# Dangerous; exposes kernel text image layout.
|
|
# CONFIG_PROC_KCORE is not set
|
|
|
|
# Dangerous; enabling this disables userspace VDSO ASLR.
|
|
# CONFIG_COMPAT_VDSO is not set
|
|
|
|
# Attack surface reduction: Use the modern PTY interface (devpts) only.
|
|
# CONFIG_LEGACY_PTYS is not set
|