stackleak: Support Clang stack depth tracking
Subsystems (41)
Kees Cook
maintainerv3 cover stackleak: Support Clang stack depth tracking
v3:
- split up and drop __init vs inline patches that went via arch trees
- apply feedback about preferring __init to __always_inline
- incorporate Ritesh Harjani's patch for __init cleanups in powerpc
- wider build testing on older compilers
v2: https://lore.kernel.org/lkml/[email protected]/
v1: https://lore.kernel.org/lkml/[email protected]/
Hi,
As part of looking at what GCC plugins could be replaced with Clang implementations, this series uses the recently landed stack depth tracking callback in Clang[1] to implement the stackleak feature. Since the Clang feature is now landed, I'm moving this out of RFC to a v1.
Since this touches a lot of arch-specific Makefiles, I tried to trim the CC list down to just mailing lists in those cases, otherwise the CC was giant.
Thanks!
-Kees
[1] https://clang.llvm.org/docs/SanitizerCoverage.html#tracing-stack-depth
Kees Cook (12):
stackleak: Rename STACKLEAK to KSTACK_ERASE
stackleak: Rename stackleak_track_stack to __sanitizer_cov_stack_depth
stackleak: Split KSTACK_ERASE_CFLAGS from GCC_PLUGINS_CFLAGS
x86: Handle KCOV __init vs inline mismatches
arm: Handle KCOV __init vs inline mismatches
arm64: Handle KCOV __init vs inline mismatches
s390: Handle KCOV __init vs inline mismatches
mips: Handle KCOV __init vs inline mismatch
init.h: Disable sanitizer coverage for __init and __head
kstack_erase: Support Clang stack depth tracking configs/hardening: Enable CONFIG_KSTACK_ERASE configs/hardening: Enable CONFIG_INIT_ON_FREE_DEFAULT_ON
Ritesh Harjani (IBM) (1):
powerpc/mm/book3s64: Move kfence and debug_pagealloc related calls to
__init section
arch/Kconfig | 4 +-
arch/arm/Kconfig | 2 +-
arch/arm64/Kconfig | 2 +-
arch/riscv/Kconfig | 2 +-
arch/s390/Kconfig | 2 +-
arch/x86/Kconfig | 2 +-
security/Kconfig.hardening | 45 +++++++++-------
Makefile | 1 +
arch/arm/boot/compressed/Makefile | 2 +-
arch/arm/vdso/Makefile | 2 +-
arch/arm64/kernel/pi/Makefile | 2 +-
arch/arm64/kernel/vdso/Makefile | 3 +-
arch/arm64/kvm/hyp/nvhe/Makefile | 2 +-
arch/riscv/kernel/pi/Makefile | 2 +-
arch/riscv/purgatory/Makefile | 2 +-
arch/sparc/vdso/Makefile | 3 +-
arch/x86/entry/vdso/Makefile | 3 +-
arch/x86/purgatory/Makefile | 2 +-
drivers/firmware/efi/libstub/Makefile | 8 +--
drivers/misc/lkdtm/Makefile | 2 +-
kernel/Makefile | 10 ++--
lib/Makefile | 2 +-
scripts/Makefile.gcc-plugins | 16 +-----
scripts/Makefile.kstack_erase | 21 ++++++++
scripts/gcc-plugins/stackleak_plugin.c | 52 +++++++++----------
Documentation/admin-guide/sysctl/kernel.rst | 4 +-
Documentation/arch/x86/x86_64/mm.rst | 2 +-
Documentation/security/self-protection.rst | 2 +-
.../zh_CN/security/self-protection.rst | 2 +-
arch/arm64/include/asm/acpi.h | 2 +-
arch/mips/include/asm/time.h | 2 +-
arch/s390/hypfs/hypfs.h | 2 +-
arch/s390/hypfs/hypfs_diag.h | 2 +-
arch/x86/entry/calling.h | 4 +-
arch/x86/include/asm/acpi.h | 4 +-
arch/x86/include/asm/init.h | 2 +-
arch/x86/include/asm/realmode.h | 2 +-
include/linux/acpi.h | 4 +-
include/linux/bootconfig.h | 2 +-
include/linux/efi.h | 2 +-
include/linux/init.h | 4 +-
include/linux/{stackleak.h => kstack_erase.h} | 20 +++----
include/linux/memblock.h | 2 +-
include/linux/mfd/dbx500-prcmu.h | 2 +-
include/linux/sched.h | 4 +-
include/linux/smp.h | 2 +-
arch/arm/kernel/entry-common.S | 2 +-
arch/arm64/kernel/entry.S | 2 +-
arch/riscv/kernel/entry.S | 2 +-
arch/s390/kernel/entry.S | 2 +-
arch/arm/mm/cache-feroceon-l2.c | 2 +-
arch/arm/mm/cache-tauros2.c | 2 +-
arch/powerpc/mm/book3s64/hash_utils.c | 6 +--
arch/powerpc/mm/book3s64/radix_pgtable.c | 4 +-
arch/s390/mm/init.c | 2 +-
arch/x86/kernel/kvm.c | 2 +-
arch/x86/mm/init_64.c | 2 +-
drivers/clocksource/timer-orion.c | 2 +-
.../lkdtm/{stackleak.c => kstack_erase.c} | 26 +++++-----
drivers/soc/ti/pm33xx.c | 2 +-
fs/proc/base.c | 6 +--
kernel/fork.c | 2 +-
kernel/kexec_handover.c | 4 +-
kernel/{stackleak.c => kstack_erase.c} | 22 ++++----
tools/objtool/check.c | 4 +-
tools/testing/selftests/lkdtm/config | 2 +-
MAINTAINERS | 6 ++-
kernel/configs/hardening.config | 6 +++
68 files changed, 204 insertions(+), 172 deletions(-)
create mode 100644 scripts/Makefile.kstack_erase
rename include/linux/{stackleak.h => kstack_erase.h} (81%)
rename drivers/misc/lkdtm/{stackleak.c => kstack_erase.c} (89%)
rename kernel/{stackleak.c => kstack_erase.c} (87%)Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v3 1/13 stackleak: Rename STACKLEAK to KSTACK_ERASE
In preparation for adding Clang sanitizer coverage stack depth tracking that can support stack depth callbacks:
- Add the new top-level CONFIG_KSTACK_ERASE option which will be implemented either with the stackleak GCC plugin, or with the Clang stack depth callback support.
- Rename CONFIG_GCC_PLUGIN_STACKLEAK as needed to CONFIG_KSTACK_ERASE, but keep it for anything specific to the GCC plugin itself.
- Rename all exposed "STACKLEAK" names and files to "KSTACK_ERASE" (named for what it does rather than what it protects against), but leave as many of the internals alone as possible to avoid even more churn.
While here, also split "prev_lowest_stack" into CONFIG_KSTACK_ERASE_METRICS, since that's the only place it is referenced from.
---
Cc: Arnd Bergmann <[email protected]>
Cc: <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
---
arch/Kconfig | 4 +--
arch/arm/Kconfig | 2 +-
arch/arm64/Kconfig | 2 +-
arch/riscv/Kconfig | 2 +-
arch/s390/Kconfig | 2 +-
arch/x86/Kconfig | 2 +-
security/Kconfig.hardening | 36 ++++++++++---------
arch/arm/boot/compressed/Makefile | 2 +-
arch/arm64/kernel/pi/Makefile | 2 +-
arch/arm64/kvm/hyp/nvhe/Makefile | 2 +-
arch/riscv/kernel/pi/Makefile | 2 +-
arch/riscv/purgatory/Makefile | 2 +-
arch/x86/purgatory/Makefile | 2 +-
drivers/firmware/efi/libstub/Makefile | 8 ++---
drivers/misc/lkdtm/Makefile | 2 +-
kernel/Makefile | 10 +++---
lib/Makefile | 2 +-
scripts/Makefile.gcc-plugins | 6 ++--
Documentation/admin-guide/sysctl/kernel.rst | 4 +--
Documentation/arch/x86/x86_64/mm.rst | 2 +-
Documentation/security/self-protection.rst | 2 +-
.../zh_CN/security/self-protection.rst | 2 +-
arch/x86/entry/calling.h | 4 +--
include/linux/{stackleak.h => kstack_erase.h} | 18 +++++-----
include/linux/sched.h | 4 ++-
arch/arm/kernel/entry-common.S | 2 +-
arch/arm64/kernel/entry.S | 2 +-
arch/riscv/kernel/entry.S | 2 +-
arch/s390/kernel/entry.S | 2 +-
.../lkdtm/{stackleak.c => kstack_erase.c} | 26 +++++++-------
fs/proc/base.c | 6 ++--
kernel/fork.c | 2 +-
kernel/{stackleak.c => kstack_erase.c} | 18 +++++-----
tools/objtool/check.c | 2 +-
tools/testing/selftests/lkdtm/config | 2 +-
MAINTAINERS | 4 +--
36 files changed, 100 insertions(+), 94 deletions(-)
rename include/linux/{stackleak.h => kstack_erase.h} (85%)
rename drivers/misc/lkdtm/{stackleak.c => kstack_erase.c} (89%)
rename kernel/{stackleak.c => kstack_erase.c} (90%)arch/Kconfig +2 -2
@@ -639,11 +639,11 @@ config SECCOMP_CACHE_DEBUG If unsure, say N. -config HAVE_ARCH_STACKLEAK +config HAVE_ARCH_KSTACK_ERASE bool help An architecture should select this if it has the code which - fills the used part of the kernel stack with the STACKLEAK_POISON + fills the used part of the kernel stack with the KSTACK_ERASE_POISON value before returning from system calls. config HAVE_STACKPROTECTOR
arch/arm/Kconfig +1 -1
@@ -85,11 +85,11 @@ config ARM select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN + select HAVE_ARCH_KSTACK_ERASE select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_PFN_VALID select HAVE_ARCH_SECCOMP select HAVE_ARCH_SECCOMP_FILTER if AEABI && !OABI_COMPAT - select HAVE_ARCH_STACKLEAK select HAVE_ARCH_THREAD_STRUCT_WHITELIST select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE if ARM_LPAE
arch/arm64/Kconfig +1 -1
@@ -184,12 +184,12 @@ config ARM64 select HAVE_ARCH_KCSAN if EXPERT select HAVE_ARCH_KFENCE select HAVE_ARCH_KGDB + select HAVE_ARCH_KSTACK_ERASE select HAVE_ARCH_MMAP_RND_BITS select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT select HAVE_ARCH_PREL32_RELOCATIONS select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET select HAVE_ARCH_SECCOMP_FILTER - select HAVE_ARCH_STACKLEAK select HAVE_ARCH_THREAD_STRUCT_WHITELIST select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE
arch/riscv/Kconfig +1 -1
@@ -133,13 +133,13 @@ config RISCV select HAVE_ARCH_KASAN if MMU && 64BIT select HAVE_ARCH_KASAN_VMALLOC if MMU && 64BIT select HAVE_ARCH_KFENCE if MMU && 64BIT + select HAVE_ARCH_KSTACK_ERASE select HAVE_ARCH_KGDB if !XIP_KERNEL select HAVE_ARCH_KGDB_QXFER_PKT select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET select HAVE_ARCH_SECCOMP_FILTER - select HAVE_ARCH_STACKLEAK select HAVE_ARCH_THREAD_STRUCT_WHITELIST select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT && MMU
arch/s390/Kconfig +1 -1
@@ -176,10 +176,10 @@ config S390 select HAVE_ARCH_KCSAN select HAVE_ARCH_KMSAN select HAVE_ARCH_KFENCE + select HAVE_ARCH_KSTACK_ERASE select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_SOFT_DIRTY - select HAVE_ARCH_STACKLEAK select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_ARCH_VMAP_STACK
arch/x86/Kconfig +1 -1
@@ -200,13 +200,13 @@ config X86 select HAVE_ARCH_KFENCE select HAVE_ARCH_KMSAN if X86_64 select HAVE_ARCH_KGDB + select HAVE_ARCH_KSTACK_ERASE select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT select HAVE_ARCH_COMPAT_MMAP_BASES if MMU && COMPAT select HAVE_ARCH_PREL32_RELOCATIONS select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_THREAD_STRUCT_WHITELIST - select HAVE_ARCH_STACKLEAK select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD if X86_64
security/Kconfig.hardening +20 -16
@@ -82,10 +82,10 @@ choice endchoice -config GCC_PLUGIN_STACKLEAK +config KSTACK_ERASE bool "Poison kernel stack before returning from syscalls" + depends on HAVE_ARCH_KSTACK_ERASE depends on GCC_PLUGINS - depends on HAVE_ARCH_STACKLEAK help This option makes the kernel erase the kernel stack before returning from system calls. This has the effect of leaving
@@ -103,6 +103,10 @@ config GCC_PLUGIN_STACKLEAK are advised to test this feature on your expected workload before deploying it. +config GCC_PLUGIN_STACKLEAK + def_bool KSTACK_ERASE + depends on GCC_PLUGINS + help This plugin was ported from grsecurity/PaX. More information at: * https://grsecurity.net/ * https://pax.grsecurity.net/
@@ -117,37 +121,37 @@ config GCC_PLUGIN_STACKLEAK_VERBOSE instrumented. This is useful for comparing coverage between builds. -config STACKLEAK_TRACK_MIN_SIZE - int "Minimum stack frame size of functions tracked by STACKLEAK" +config KSTACK_ERASE_TRACK_MIN_SIZE + int "Minimum stack frame size of functions tracked by KSTACK_ERASE" default 100 range 0 4096 - depends on GCC_PLUGIN_STACKLEAK + depends on KSTACK_ERASE help - The STACKLEAK gcc plugin instruments the kernel code for tracking + The KSTACK_ERASE option instruments the kernel code for tracking the lowest border of the kernel stack (and for some other purposes). It inserts the stackleak_track_stack() call for the functions with a stack frame size greater than or equal to this parameter. If unsure, leave the default value 100. -config STACKLEAK_METRICS - bool "Show STACKLEAK metrics in the /proc file system" - depends on GCC_PLUGIN_STACKLEAK +config KSTACK_ERASE_METRICS + bool "Show KSTACK_ERASE metrics in the /proc file system" + depends on KSTACK_ERASE depends on PROC_FS help - If this is set, STACKLEAK metrics for every task are available in - the /proc file system. In particular, /proc/<pid>/stack_depth + If this is set, KSTACK_ERASE metrics for every task are available + in the /proc file system. In particular, /proc/<pid>/stack_depth shows the maximum kernel stack consumption for the current and previous syscalls. Although this information is not precise, it - can be useful for estimating the STACKLEAK performance impact for - your workloads. + can be useful for estimating the KSTACK_ERASE performance impact + for your workloads. -config STACKLEAK_RUNTIME_DISABLE +config KSTACK_ERASE_RUNTIME_DISABLE bool "Allow runtime disabling of kernel stack erasing" - depends on GCC_PLUGIN_STACKLEAK + depends on KSTACK_ERASE help This option provides 'stack_erasing' sysctl, which can be used in runtime to control kernel stack erasing for kernels built with - CONFIG_GCC_PLUGIN_STACKLEAK. + CONFIG_KSTACK_ERASE. config INIT_ON_ALLOC_DEFAULT_ON bool "Enable heap memory zeroing on allocation by default"
arch/arm/boot/compressed/Makefile +1 -1
@@ -9,7 +9,7 @@ OBJS = HEAD = head.o OBJS += misc.o decompress.o -CFLAGS_decompress.o += $(DISABLE_STACKLEAK_PLUGIN) +CFLAGS_decompress.o += $(DISABLE_KSTACK_ERASE) ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y) OBJS += debug.o AFLAGS_head.o += -DDEBUG
arch/arm64/kernel/pi/Makefile +1 -1
@@ -2,7 +2,7 @@ # Copyright 2022 Google LLC KBUILD_CFLAGS := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) -fpie \ - -Os -DDISABLE_BRANCH_PROFILING $(DISABLE_STACKLEAK_PLUGIN) \ + -Os -DDISABLE_BRANCH_PROFILING $(DISABLE_KSTACK_ERASE) \ $(DISABLE_LATENT_ENTROPY_PLUGIN) \ $(call cc-option,-mbranch-protection=none) \ -I$(srctree)/scripts/dtc/libfdt -fno-stack-protector \
arch/arm64/kvm/hyp/nvhe/Makefile +1 -1
@@ -12,7 +12,7 @@ asflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS -D__DISABLE_TRACE_MMIO__ ccflags-y += -fno-stack-protector \ -DDISABLE_BRANCH_PROFILING \ - $(DISABLE_STACKLEAK_PLUGIN) + $(DISABLE_KSTACK_ERASE) hostprogs := gen-hyprel HOST_EXTRACFLAGS += -I$(objtree)/include
arch/riscv/kernel/pi/Makefile +1 -1
@@ -2,7 +2,7 @@ # This file was copied from arm64/kernel/pi/Makefile. KBUILD_CFLAGS := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) -fpie \ - -Os -DDISABLE_BRANCH_PROFILING $(DISABLE_STACKLEAK_PLUGIN) \ + -Os -DDISABLE_BRANCH_PROFILING $(DISABLE_KSTACK_ERASE) \ $(call cc-option,-mbranch-protection=none) \ -I$(srctree)/scripts/dtc/libfdt -fno-stack-protector \ -include $(srctree)/include/linux/hidden.h \
arch/riscv/purgatory/Makefile +1 -1
@@ -53,7 +53,7 @@ targets += purgatory.ro purgatory.chk PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel PURGATORY_CFLAGS := -mcmodel=medany -ffreestanding -fno-zero-initialized-in-bss -PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN) -DDISABLE_BRANCH_PROFILING +PURGATORY_CFLAGS += $(DISABLE_KSTACK_ERASE) -DDISABLE_BRANCH_PROFILING PURGATORY_CFLAGS += -fno-stack-protector -g0 # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That
arch/x86/purgatory/Makefile +1 -1
@@ -35,7 +35,7 @@ targets += purgatory.ro purgatory.chk PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel PURGATORY_CFLAGS := -mcmodel=small -ffreestanding -fno-zero-initialized-in-bss -g0 PURGATORY_CFLAGS += -fpic -fvisibility=hidden -PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN) -DDISABLE_BRANCH_PROFILING +PURGATORY_CFLAGS += $(DISABLE_KSTACK_ERASE) -DDISABLE_BRANCH_PROFILING PURGATORY_CFLAGS += -fno-stack-protector # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That
drivers/firmware/efi/libstub/Makefile +4 -4
@@ -22,16 +22,16 @@ cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -std=gnu11 \ # arm64 uses the full KBUILD_CFLAGS so it's necessary to explicitly # disable the stackleak plugin -cflags-$(CONFIG_ARM64) += -fpie $(DISABLE_STACKLEAK_PLUGIN) \ +cflags-$(CONFIG_ARM64) += -fpie $(DISABLE_KSTACK_ERASE) \ -fno-unwind-tables -fno-asynchronous-unwind-tables cflags-$(CONFIG_ARM) += -DEFI_HAVE_STRLEN -DEFI_HAVE_STRNLEN \ -DEFI_HAVE_MEMCHR -DEFI_HAVE_STRRCHR \ -DEFI_HAVE_STRCMP -fno-builtin -fpic \ $(call cc-option,-mno-single-pic-base) \ - $(DISABLE_STACKLEAK_PLUGIN) + $(DISABLE_KSTACK_ERASE) cflags-$(CONFIG_RISCV) += -fpic -DNO_ALTERNATIVE -mno-relax \ - $(DISABLE_STACKLEAK_PLUGIN) -cflags-$(CONFIG_LOONGARCH) += -fpie $(DISABLE_STACKLEAK_PLUGIN) + $(DISABLE_KSTACK_ERASE) +cflags-$(CONFIG_LOONGARCH) += -fpie $(DISABLE_KSTACK_ERASE) cflags-$(CONFIG_EFI_PARAMS_FROM_FDT) += -I$(srctree)/scripts/dtc/libfdt
drivers/misc/lkdtm/Makefile +1 -1
@@ -8,7 +8,7 @@ lkdtm-$(CONFIG_LKDTM) += perms.o lkdtm-$(CONFIG_LKDTM) += refcount.o lkdtm-$(CONFIG_LKDTM) += rodata_objcopy.o lkdtm-$(CONFIG_LKDTM) += usercopy.o -lkdtm-$(CONFIG_LKDTM) += stackleak.o +lkdtm-$(CONFIG_LKDTM) += kstack_erase.o lkdtm-$(CONFIG_LKDTM) += cfi.o lkdtm-$(CONFIG_LKDTM) += fortify.o lkdtm-$(CONFIG_PPC_64S_HASH_MMU) += powerpc.o
kernel/Makefile +5 -5
@@ -139,11 +139,11 @@ obj-$(CONFIG_WATCH_QUEUE) += watch_queue.o obj-$(CONFIG_RESOURCE_KUNIT_TEST) += resource_kunit.o obj-$(CONFIG_SYSCTL_KUNIT_TEST) += sysctl-test.o -CFLAGS_stackleak.o += $(DISABLE_STACKLEAK_PLUGIN) -obj-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak.o -KASAN_SANITIZE_stackleak.o := n -KCSAN_SANITIZE_stackleak.o := n -KCOV_INSTRUMENT_stackleak.o := n +CFLAGS_kstack_erase.o += $(DISABLE_KSTACK_ERASE) +obj-$(CONFIG_KSTACK_ERASE) += kstack_erase.o +KASAN_SANITIZE_kstack_erase.o := n +KCSAN_SANITIZE_kstack_erase.o := n +KCOV_INSTRUMENT_kstack_erase.o := n obj-$(CONFIG_SCF_TORTURE_TEST) += scftorture.o
lib/Makefile +1 -1
@@ -307,7 +307,7 @@ obj-$(CONFIG_UBSAN) += ubsan.o UBSAN_SANITIZE_ubsan.o := n KASAN_SANITIZE_ubsan.o := n KCSAN_SANITIZE_ubsan.o := n -CFLAGS_ubsan.o := -fno-stack-protector $(DISABLE_STACKLEAK_PLUGIN) +CFLAGS_ubsan.o := -fno-stack-protector $(DISABLE_KSTACK_ERASE) obj-$(CONFIG_SBITMAP) += sbitmap.o
scripts/Makefile.gcc-plugins +3 -3
@@ -12,15 +12,15 @@ gcc-plugin-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak_plugin.so gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ += -DSTACKLEAK_PLUGIN gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ - += -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_STACKLEAK_TRACK_MIN_SIZE) + += -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_KSTACK_ERASE_TRACK_MIN_SIZE) gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ += -fplugin-arg-stackleak_plugin-arch=$(SRCARCH) gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK_VERBOSE) \ += -fplugin-arg-stackleak_plugin-verbose ifdef CONFIG_GCC_PLUGIN_STACKLEAK - DISABLE_STACKLEAK_PLUGIN += -fplugin-arg-stackleak_plugin-disable + DISABLE_KSTACK_ERASE += -fplugin-arg-stackleak_plugin-disable endif -export DISABLE_STACKLEAK_PLUGIN +export DISABLE_KSTACK_ERASE # All the plugin CFLAGS are collected here in case a build target needs to # filter them out of the KBUILD_CFLAGS.
Documentation/admin-guide/sysctl/kernel.rst +2 -2
@@ -1480,7 +1480,7 @@ stack_erasing ============= This parameter can be used to control kernel stack erasing at the end -of syscalls for kernels built with ``CONFIG_GCC_PLUGIN_STACKLEAK``. +of syscalls for kernels built with ``CONFIG_KSTACK_ERASE``. That erasing reduces the information which kernel stack leak bugs can reveal and blocks some uninitialized stack variable attacks.
@@ -1488,7 +1488,7 @@ The tradeoff is the performance impact: on a single CPU system kernel compilation sees a 1% slowdown, other systems and workloads may vary. = ==================================================================== -0 Kernel stack erasing is disabled, STACKLEAK_METRICS are not updated. +0 Kernel stack erasing is disabled, KSTACK_ERASE_METRICS are not updated. 1 Kernel stack erasing is enabled (default), it is performed before returning to the userspace at the end of syscalls. = ====================================================================
Documentation/arch/x86/x86_64/mm.rst +1 -1
@@ -176,5 +176,5 @@ Be very careful vs. KASLR when changing anything here. The KASLR address range must not overlap with anything except the KASAN shadow area, which is correct as KASAN disables KASLR. -For both 4- and 5-level layouts, the STACKLEAK_POISON value in the last 2MB +For both 4- and 5-level layouts, the KSTACK_ERASE_POISON value in the last 2MB hole: ffffffffffff4111
Documentation/security/self-protection.rst +1 -1
@@ -303,7 +303,7 @@ Memory poisoning When releasing memory, it is best to poison the contents, to avoid reuse attacks that rely on the old contents of memory. E.g., clear stack on a -syscall return (``CONFIG_GCC_PLUGIN_STACKLEAK``), wipe heap memory on a +syscall return (``CONFIG_KSTACK_ERASE``), wipe heap memory on a free. This frustrates many uninitialized variable attacks, stack content exposures, heap content exposures, and use-after-free attacks.
Documentation/translations/zh_CN/security/self-protection.rst +1 -1
@@ -259,7 +259,7 @@ KALLSYSM,则会直接打印原始地址。 -------- 在释放内存时,最好对内存内容进行清除处理,以防止攻击者重用内存中以前 -的内容。例如,在系统调用返回时清除堆栈(CONFIG_GCC_PLUGIN_STACKLEAK), +的内容。例如,在系统调用返回时清除堆栈(CONFIG_KSTACK_ERASE), 在释放堆内容是清除其内容。这有助于防止许多未初始化变量攻击、堆栈内容 泄露、堆内容泄露以及使用后释放攻击(user-after-free)。
arch/x86/entry/calling.h +2 -2
@@ -369,7 +369,7 @@ For 32-bit we have the following conventions - kernel is built with .endm .macro STACKLEAK_ERASE_NOCLOBBER -#ifdef CONFIG_GCC_PLUGIN_STACKLEAK +#ifdef CONFIG_KSTACK_ERASE PUSH_AND_CLEAR_REGS call stackleak_erasePOP_REGS
@@ -388,7 +388,7 @@ For 32-bit we have the following conventions - kernel is built with#endif /* !CONFIG_X86_64 */ .macro STACKLEAK_ERASE -#ifdef CONFIG_GCC_PLUGIN_STACKLEAK +#ifdef CONFIG_KSTACK_ERASE call stackleak_erase #endif .endm
include/linux/kstack_erase.h renamed from include/linux/stackleak.h +9 -9
@@ -1,6 +1,6 @@/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _LINUX_STACKLEAK_H -#define _LINUX_STACKLEAK_H +#ifndef _LINUX_KSTACK_ERASE_H +#define _LINUX_KSTACK_ERASE_H#include <linux/sched.h> #include <linux/sched/task_stack.h>
@@ -9,10 +9,10 @@* Check that the poison value points to the unused hole in the * virtual memory map for your platform. */ -#define STACKLEAK_POISON -0xBEEF -#define STACKLEAK_SEARCH_DEPTH 128 +#define KSTACK_ERASE_POISON -0xBEEF +#define KSTACK_ERASE_SEARCH_DEPTH 128 -#ifdef CONFIG_GCC_PLUGIN_STACKLEAK +#ifdef CONFIG_KSTACK_ERASE #include <asm/stacktrace.h> #include <linux/linkage.h>
@@ -50,7 +50,7 @@ stackleak_task_high_bound(const struct task_struct *tsk)static __always_inline unsigned long stackleak_find_top_of_poison (const unsigned long low,const unsigned long high) { -const unsigned int depth =STACKLEAK_SEARCH_DEPTH /sizeof (unsigned long ); +const unsigned int depth =KSTACK_ERASE_SEARCH_DEPTH /sizeof (unsigned long );unsigned int poison_count =0 ;unsigned long poison_high = high;unsigned long sp = high;
@@ -58,7 +58,7 @@ stackleak_find_top_of_poison(const unsigned long low, const unsigned long high)while (sp > low && poison_count < depth) { sp -=sizeof (unsigned long ); -if (*(unsigned long *)sp ==STACKLEAK_POISON ) { +if (*(unsigned long *)sp ==KSTACK_ERASE_POISON ) { poison_count++; }else { poison_count =0 ;
@@ -72,7 +72,7 @@ stackleak_find_top_of_poison(const unsigned long low, const unsigned long high)static inline void stackleak_task_init (struct task_struct *t) { t->lowest_stack =stackleak_task_low_bound (t); -# ifdef CONFIG_STACKLEAK_METRICS +# ifdef CONFIG_KSTACK_ERASE_METRICS t->prev_lowest_stack = t->lowest_stack;# endif }
@@ -82,7 +82,7 @@ asmlinkage void noinstr stackleak_erase_on_task_stack(void); asmlinkage void noinstr stackleak_erase_off_task_stack(void); void __no_caller_saved_registers noinstr stackleak_track_stack(void); -#else /* !CONFIG_GCC_PLUGIN_STACKLEAK */ +#else /* !CONFIG_KSTACK_ERASE */ static inline void stackleak_task_init (struct task_struct *t) { }#endif
include/linux/sched.h +3 -1
@@ -1590,8 +1590,10 @@ struct task_struct {/* Used by BPF for per-TASK xdp storage */ struct bpf_net_context *bpf_net_context; -#ifdef CONFIG_GCC_PLUGIN_STACKLEAK +#ifdef CONFIG_KSTACK_ERASE unsigned long lowest_stack; +#endif +#ifdef CONFIG_KSTACK_ERASE_METRICS unsigned long prev_lowest_stack;#endif
arch/arm/kernel/entry-common.S +1 -1
@@ -119,7 +119,7 @@ no_work_pending: ct_user_enter save = 0 -#ifdef CONFIG_GCC_PLUGIN_STACKLEAK +#ifdef CONFIG_KSTACK_ERASE bl stackleak_erase_on_task_stack #endif restore_user_regs fast = 0, offset = 0
arch/arm64/kernel/entry.S +1 -1
@@ -614,7 +614,7 @@ SYM_CODE_END(ret_to_kernel) SYM_CODE_START_LOCAL(ret_to_user) ldr x19, [tsk, #TSK_TI_FLAGS] // re-check for single-step enable_step_tsk x19, x2 -#ifdef CONFIG_GCC_PLUGIN_STACKLEAK +#ifdef CONFIG_KSTACK_ERASE bl stackleak_erase_on_task_stack #endif kernel_exit 0
arch/riscv/kernel/entry.S +1 -1
@@ -220,7 +220,7 @@ SYM_CODE_START_NOALIGN(ret_from_exception) #endif bnez s0, 1f -#ifdef CONFIG_GCC_PLUGIN_STACKLEAK +#ifdef CONFIG_KSTACK_ERASE call stackleak_erase_on_task_stack #endif
arch/s390/kernel/entry.S +1 -1
@@ -124,7 +124,7 @@ _LPP_OFFSET = __LC_LPP #endif .macro STACKLEAK_ERASE -#ifdef CONFIG_GCC_PLUGIN_STACKLEAK +#ifdef CONFIG_KSTACK_ERASE brasl %r14,stackleak_erase_on_task_stack #endif .endm
drivers/misc/lkdtm/kstack_erase.c renamed from drivers/misc/lkdtm/stackleak.c +13 -13
@@ -1,7 +1,7 @@// SPDX-License-Identifier: GPL-2.0 /* * This code tests that the current task stack is properly erased (filled -* with STACKLEAK_POISON). +* with KSTACK_ERASE_POISON). * * Authors: * Alexander Popov <[email protected]>
@@ -9,9 +9,9 @@*/ #include "lkdtm.h" -#include <linux/stackleak.h> +#include <linux/kstack_erase.h> -#if defined(CONFIG_GCC_PLUGIN_STACKLEAK ) +#if defined(CONFIG_KSTACK_ERASE )/* * Check that stackleak tracks the lowest stack pointer and erases the stack * below this as expected.
@@ -85,7 +85,7 @@ static void noinstr check_stackleak_irqoff(void)while (poison_low > task_stack_low) { poison_low -=sizeof (unsigned long ); -if (*(unsigned long *)poison_low ==STACKLEAK_POISON ) +if (*(unsigned long *)poison_low ==KSTACK_ERASE_POISON )continue ;instrumentation_begin ();
@@ -96,7 +96,7 @@ static void noinstr check_stackleak_irqoff(void) }instrumentation_begin (); -pr_info ("stackleak stack usage:\n" +pr_info ("kstack erase stack usage:\n" " high offset: %lu bytes\n" " current: %lu bytes\n" " lowest: %lu bytes\n"
@@ -121,7 +121,7 @@ static void noinstr check_stackleak_irqoff(void)instrumentation_end (); } -static void lkdtm_STACKLEAK_ERASING (void ) +static void lkdtm_KSTACK_ERASE (void ) {unsigned long flags;
@@ -129,19 +129,19 @@ static void lkdtm_STACKLEAK_ERASING(void)check_stackleak_irqoff ();local_irq_restore (flags); } -#else /* defined(CONFIG_GCC_PLUGIN_STACKLEAK) */ -static void lkdtm_STACKLEAK_ERASING (void ) +#else /* defined(CONFIG_KSTACK_ERASE) */ +static void lkdtm_KSTACK_ERASE (void ) { -if (IS_ENABLED (CONFIG_HAVE_ARCH_STACKLEAK )) { -pr_err ("XFAIL: stackleak is not enabled (CONFIG_GCC_PLUGIN_STACKLEAK=n)\n" ); +if (IS_ENABLED (CONFIG_HAVE_ARCH_KSTACK_ERASE )) { +pr_err ("XFAIL: stackleak is not enabled (CONFIG_KSTACK_ERASE=n)\n" ); }else { -pr_err ("XFAIL: stackleak is not supported on this arch (HAVE_ARCH_STACKLEAK=n)\n" ); +pr_err ("XFAIL: stackleak is not supported on this arch (HAVE_ARCH_KSTACK_ERASE=n)\n" ); } } -#endif /* defined(CONFIG_GCC_PLUGIN_STACKLEAK) */ +#endif /* defined(CONFIG_KSTACK_ERASE) */ static struct crashtype crashtypes[] = { -CRASHTYPE (STACKLEAK_ERASING ), +CRASHTYPE (KSTACK_ERASE ), };struct crashtype_category stackleak_crashtypes = {
fs/proc/base.c +3 -3
@@ -3290,7 +3290,7 @@ static int proc_pid_ksm_stat(struct seq_file *m, struct pid_namespace *ns, }#endif /* CONFIG_KSM */ -#ifdef CONFIG_STACKLEAK_METRICS +#ifdef CONFIG_KSTACK_ERASE_METRICS static int proc_stack_depth (struct seq_file *m,struct pid_namespace *ns,struct pid *pid,struct task_struct *task) {
@@ -3303,7 +3303,7 @@ static int proc_stack_depth(struct seq_file *m, struct pid_namespace *ns, prev_depth, depth); return 0; } -#endif /* CONFIG_STACKLEAK_METRICS */ +#endif /* CONFIG_KSTACK_ERASE_METRICS */ /* * Thread groups
@@ -3410,7 +3410,7 @@ static const struct pid_entry tgid_base_stuff[] = {#ifdef CONFIG_LIVEPATCH ONE("patch_state", S_IRUSR, proc_pid_patch_state),#endif -#ifdef CONFIG_STACKLEAK_METRICS +#ifdef CONFIG_KSTACK_ERASE_METRICS ONE ("stack_depth" ,S_IRUGO , proc_stack_depth), #endif #ifdef CONFIG_PROC_PID_ARCH_STATUS
kernel/fork.c +1 -1
@@ -93,7 +93,7 @@#include <linux/kcov.h> #include <linux/livepatch.h> #include <linux/thread_info.h> -#include <linux/stackleak.h> +#include <linux/kstack_erase.h> #include <linux/kasan.h> #include <linux/scs.h> #include <linux/io_uring.h>
kernel/kstack_erase.c renamed from kernel/stackleak.c +9 -9
@@ -6,14 +6,14 @@* * Author: Alexander Popov <[email protected]> * -* STACKLEAK reduces the information which kernel stack leak bugs can +* KSTACK_ERASE reduces the information which kernel stack leak bugs can * reveal and blocks some uninitialized stack variable attacks. */ -#include <linux/stackleak.h> +#include <linux/kstack_erase.h> #include <linux/kprobes.h> -#ifdef CONFIG_STACKLEAK_RUNTIME_DISABLE +#ifdef CONFIG_KSTACK_ERASE_RUNTIME_DISABLE #include <linux/jump_label.h> #include <linux/string_choices.h> #include <linux/sysctl.h>
@@ -68,7 +68,7 @@ late_initcall(stackleak_sysctls_init);#define skip_erasing () static_branch_unlikely(&stack_erasing_bypass)#else #define skip_erasing () false -#endif /* CONFIG_STACKLEAK_RUNTIME_DISABLE */ +#endif /* CONFIG_KSTACK_ERASE_RUNTIME_DISABLE */ #ifndef __stackleak_poison static __always_inline void __stackleak_poison(unsigned long erase_low,
@@ -91,7 +91,7 @@ static __always_inline void __stackleak_erase(bool on_task_stack) erase_low =stackleak_find_top_of_poison (task_stack_low, current->lowest_stack); -#ifdef CONFIG_STACKLEAK_METRICS +#ifdef CONFIG_KSTACK_ERASE_METRICS current->prev_lowest_stack = erase_low;#endif
@@ -113,7 +113,7 @@ static __always_inline void __stackleak_erase(bool on_task_stack)else erase_high = task_stack_high; -__stackleak_poison (erase_low, erase_high,STACKLEAK_POISON ); +__stackleak_poison (erase_low, erase_high,KSTACK_ERASE_POISON );/* Reset the 'lowest_stack' value for the next syscall */ current->lowest_stack = task_stack_high;
@@ -161,11 +161,11 @@ void __used __no_caller_saved_registers noinstr stackleak_track_stack(void)unsigned long sp = current_stack_pointer;/* -* Having CONFIG_STACKLEAK_TRACK_MIN_SIZE larger than -* STACKLEAK_SEARCH_DEPTH makes the poison search in +* Having CONFIG_KSTACK_ERASE_TRACK_MIN_SIZE larger than +* KSTACK_ERASE_SEARCH_DEPTH makes the poison search in * stackleak_erase() unreliable. Let's prevent that. */ -BUILD_BUG_ON (CONFIG_STACKLEAK_TRACK_MIN_SIZE >STACKLEAK_SEARCH_DEPTH ); +BUILD_BUG_ON (CONFIG_KSTACK_ERASE_TRACK_MIN_SIZE >KSTACK_ERASE_SEARCH_DEPTH );/* 'lowest_stack' should be aligned on the register width boundary */ sp =ALIGN (sp,sizeof (unsigned long ));
tools/objtool/check.c +1 -1
@@ -1192,7 +1192,7 @@ static const char *uaccess_safe_builtin[] = {"__ubsan_handle_type_mismatch_v1" ,"__ubsan_handle_shift_out_of_bounds" ,"__ubsan_handle_load_invalid_value" , -/* STACKLEAK */ +/* KSTACK_ERASE */ "stackleak_track_stack" ,/* TRACE_BRANCH_PROFILING */ "ftrace_likely_update",
tools/testing/selftests/lkdtm/config +1 -1
@@ -2,7 +2,7 @@ CONFIG_LKDTM=y CONFIG_DEBUG_LIST=y CONFIG_SLAB_FREELIST_HARDENED=y CONFIG_FORTIFY_SOURCE=y -CONFIG_GCC_PLUGIN_STACKLEAK=y +CONFIG_KSTACK_ERASE=y CONFIG_HARDENED_USERCOPY=y CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y CONFIG_INIT_ON_FREE_DEFAULT_ON=y
MAINTAINERS +2 -2
@@ -10056,8 +10056,6 @@ L: [email protected] S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening F: Documentation/kbuild/gcc-plugins.rst -F: include/linux/stackleak.h -F: kernel/stackleak.c F: scripts/Makefile.gcc-plugins F: scripts/gcc-plugins/
@@ -13174,10 +13172,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/har F: Documentation/ABI/testing/sysfs-kernel-oops_count F: Documentation/ABI/testing/sysfs-kernel-warn_count F: arch/*/configs/hardening.config +F: include/linux/kstack_erase.h F: include/linux/overflow.h F: include/linux/randomize_kstack.h F: include/linux/ucopysize.h F: kernel/configs/hardening.config +F: kernel/kstack_erase.c F: lib/tests/randstruct_kunit.c F: lib/tests/usercopy_kunit.c F: mm/usercopy.c
Signature · 1 line
2.34.1
Re: [PATCH v3 01/13] stackleak: Rename STACKLEAK to KSTACK_ERASE
Quoted 31 lines · Kees Cook
In preparation for adding Clang sanitizer coverage stack depth tracking that can support stack depth callbacks:
- Add the new top-level
CONFIG_KSTACK_ERASEoption which will be implemented either with the stackleak GCC plugin, or with the Clang stack depth callback support.
- RenameCONFIG_GCC_PLUGIN_STACKLEAKas needed toCONFIG_KSTACK_ERASE, but keep it for anything specific to the GCC plugin itself.
- Rename all exposed "STACKLEAK" names and files to "KSTACK_ERASE" (named for what it does rather than what it protects against), but leave as many of the internals alone as possible to avoid even more churn.While here, also split "
prev_lowest_stack" intoCONFIG_KSTACK_ERASE_METRICS, since that's the only place it is referenced from.Suggested-by Ingo Molnar <[email protected]>Signed-off-by Kees Cook <[email protected]>---
Cc: Arnd Bergmann <[email protected]>
Cc: <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Quoted 14 lines
--- arch/Kconfig | 4 +-- arch/arm/Kconfig | 2 +- arch/arm64/Kconfig | 2 +- arch/riscv/Kconfig | 2 +- arch/s390/Kconfig | 2 +- arch/x86/Kconfig | 2 +- security/Kconfig.hardening | 36 ++++++++++--------- arch/arm/boot/compressed/Makefile | 2 +- arch/arm64/kernel/pi/Makefile | 2 +- arch/arm64/kvm/hyp/nvhe/Makefile | 2 +- arch/riscv/kernel/pi/Makefile | 2 +- arch/riscv/purgatory/Makefile | 2 +- arch/x86/purgatory/Makefile | 2 +-
Did you miss arch/loongarch/Kconfig by accident?
$ git grep -Hrne ARCH_STACKLEAK arch/loongarch/Kconfig:127: select HAVE_ARCH_STACKLEAK
Kind regards,
Nicolas
Kees Cook
maintainerRe: [PATCH v3 01/13] stackleak: Rename STACKLEAK to KSTACK_ERASE
Quoted 47 lines · Nicolas Schier
Quoted 31 lines · Kees Cook
In preparation for adding Clang sanitizer coverage stack depth tracking that can support stack depth callbacks:
- Add the new top-level
CONFIG_KSTACK_ERASEoption which will be implemented either with the stackleak GCC plugin, or with the Clang stack depth callback support.
- RenameCONFIG_GCC_PLUGIN_STACKLEAKas needed toCONFIG_KSTACK_ERASE, but keep it for anything specific to the GCC plugin itself.
- Rename all exposed "STACKLEAK" names and files to "KSTACK_ERASE" (named for what it does rather than what it protects against), but leave as many of the internals alone as possible to avoid even more churn.While here, also split "
prev_lowest_stack" intoCONFIG_KSTACK_ERASE_METRICS, since that's the only place it is referenced from.Suggested-by Ingo Molnar <[email protected]>Signed-off-by Kees Cook <[email protected]>---
Cc: Arnd Bergmann <[email protected]>
Cc: <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>Quoted 14 lines
--- arch/Kconfig | 4 +-- arch/arm/Kconfig | 2 +- arch/arm64/Kconfig | 2 +- arch/riscv/Kconfig | 2 +- arch/s390/Kconfig | 2 +- arch/x86/Kconfig | 2 +- security/Kconfig.hardening | 36 ++++++++++--------- arch/arm/boot/compressed/Makefile | 2 +- arch/arm64/kernel/pi/Makefile | 2 +- arch/arm64/kvm/hyp/nvhe/Makefile | 2 +- arch/riscv/kernel/pi/Makefile | 2 +- arch/riscv/purgatory/Makefile | 2 +- arch/x86/purgatory/Makefile | 2 +-
Quoted 4 lines
Did you miss
arch/loongarch/Kconfigby accident?$ git grep -Hrne ARCH_STACKLEAK arch/loongarch/Kconfig:127: select HAVE_ARCH_STACKLEAK
Oh! Yes, I missed that when I rebased to v6.16 (which added loongarch support for stackleak). Thanks for catching that!
Signature · 1 line
Kees Cook
Kees Cook
maintainerPATCH v3 2/13 stackleak: Rename stackleak_track_stack to __sanitizer_cov_stack_depth
In reply to Kees CookThe Clang stack depth tracking implementation has a fixed name for the stack depth tracking callback, "__sanitizer_cov_stack_depth", so rename the GCC plugin function to match since the plugin has no external dependencies on naming.
---
Cc: Arnd Bergmann <[email protected]>
Cc: <[email protected]>
--- security/Kconfig.hardening | 4 +- scripts/gcc-plugins/stackleak_plugin.c | 52 +++++++++++++------------- include/linux/kstack_erase.h | 2 +- kernel/kstack_erase.c | 4 +- tools/objtool/check.c | 2 +- 5 files changed, 32 insertions(+), 32 deletions(-)
security/Kconfig.hardening +2 -2
@@ -129,8 +129,8 @@ config KSTACK_ERASE_TRACK_MIN_SIZE help The KSTACK_ERASE option instruments the kernel code for tracking the lowest border of the kernel stack (and for some other purposes). - It inserts the stackleak_track_stack() call for the functions with - a stack frame size greater than or equal to this parameter. + It inserts the __sanitizer_cov_stack_depth() call for the functions + with a stack frame size greater than or equal to this parameter. If unsure, leave the default value 100. config KSTACK_ERASE_METRICS
scripts/gcc-plugins/stackleak_plugin.c +26 -26
159 lines not on this page · raw message
include/linux/kstack_erase.h +1 -1
@@ -80,7 +80,7 @@ static inline void stackleak_task_init(struct task_struct *t) asmlinkage void noinstr stackleak_erase(void); asmlinkage void noinstr stackleak_erase_on_task_stack(void); asmlinkage void noinstr stackleak_erase_off_task_stack(void); -void __no_caller_saved_registers noinstr stackleak_track_stack(void); +void __no_caller_saved_registers noinstr __sanitizer_cov_stack_depth(void);#else /* !CONFIG_KSTACK_ERASE */ static inline void stackleak_task_init (struct task_struct *t) { }
kernel/kstack_erase.c +2 -2
@@ -156,7 +156,7 @@ asmlinkage void noinstr stackleak_erase_off_task_stack(void)__stackleak_erase (false); } -void __used __no_caller_saved_registers noinstr stackleak_track_stack(void) +void __used __no_caller_saved_registers noinstr __sanitizer_cov_stack_depth(void) {unsigned long sp = current_stack_pointer;
@@ -174,4 +174,4 @@ void __used __no_caller_saved_registers noinstr stackleak_track_stack(void) current->lowest_stack = sp; } } -EXPORT_SYMBOL (stackleak_track_stack); +EXPORT_SYMBOL (__sanitizer_cov_stack_depth);
tools/objtool/check.c +1 -1
@@ -1193,7 +1193,7 @@ static const char *uaccess_safe_builtin[] = {"__ubsan_handle_shift_out_of_bounds" ,"__ubsan_handle_load_invalid_value" ,/* KSTACK_ERASE */ -"stackleak_track_stack" , +"__sanitizer_cov_stack_depth" ,/* TRACE_BRANCH_PROFILING */ "ftrace_likely_update",/* STACKPROTECTOR */
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v3 3/13 stackleak: Split KSTACK_ERASE_CFLAGS from GCC_PLUGINS_CFLAGS
In reply to Kees CookIn preparation for Clang stack depth tracking for KSTACK_ERASE, split the stackleak-specific cflags out of GCC_PLUGINS_CFLAGS into KSTACK_ERASE_CFLAGS.
---
Cc: Arnd Bergmann <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
--- Makefile | 1 + arch/arm/vdso/Makefile | 2 +- arch/arm64/kernel/vdso/Makefile | 3 ++- arch/sparc/vdso/Makefile | 3 ++- arch/x86/entry/vdso/Makefile | 3 ++- scripts/Makefile.gcc-plugins | 16 ++-------------- scripts/Makefile.kstack_erase | 15 +++++++++++++++ MAINTAINERS | 2 ++ 8 files changed, 27 insertions(+), 18 deletions(-) create mode 100644 scripts/Makefile.kstack_erase
Makefile +1 -0
@@ -1092,6 +1092,7 @@ include-$(CONFIG_KMSAN) += scripts/Makefile.kmsan include-$(CONFIG_UBSAN) += scripts/Makefile.ubsan include-$(CONFIG_KCOV) += scripts/Makefile.kcov include-$(CONFIG_RANDSTRUCT) += scripts/Makefile.randstruct +include-$(CONFIG_KSTACK_ERASE) += scripts/Makefile.kstack_erase include-$(CONFIG_AUTOFDO_CLANG) += scripts/Makefile.autofdo include-$(CONFIG_PROPELLER_CLANG) += scripts/Makefile.propeller include-$(CONFIG_GCC_PLUGINS) += scripts/Makefile.gcc-plugins
arch/arm/vdso/Makefile +1 -1
@@ -26,7 +26,7 @@ CPPFLAGS_vdso.lds += -P -C -U$(ARCH) CFLAGS_REMOVE_vdso.o = -pg # Force -O2 to avoid libgcc dependencies -CFLAGS_REMOVE_vgettimeofday.o = -pg -Os $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) +CFLAGS_REMOVE_vgettimeofday.o = -pg -Os $(RANDSTRUCT_CFLAGS) $(KSTACK_ERASE_CFLAGS) $(GCC_PLUGINS_CFLAGS) ifeq ($(c-gettimeofday-y),) CFLAGS_vgettimeofday.o = -O2 else
arch/arm64/kernel/vdso/Makefile +2 -1
@@ -36,7 +36,8 @@ ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO # -Wmissing-prototypes and -Wmissing-declarations are removed from # the CFLAGS to make possible to build the kernel with CONFIG_WERROR enabled. CC_FLAGS_REMOVE_VDSO := $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \ - $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) \ + $(RANDSTRUCT_CFLAGS) $(KSTACK_ERASE_CFLAGS) \ + $(GCC_PLUGINS_CFLAGS) \ $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \ -Wmissing-prototypes -Wmissing-declarations
arch/sparc/vdso/Makefile +2 -1
@@ -48,7 +48,7 @@ CFL := $(PROFILING) -mcmodel=medlow -fPIC -O2 -fasynchronous-unwind-tables -m64 SPARC_REG_CFLAGS = -ffixed-g4 -ffixed-g5 $(call cc-option,-fcall-used-g5) $(call cc-option,-fcall-used-g7) -$(vobjs): KBUILD_CFLAGS := $(filter-out $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) $(SPARC_REG_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) +$(vobjs): KBUILD_CFLAGS := $(filter-out $(RANDSTRUCT_CFLAGS) $(KSTACK_ERASE_CFLAGS) $(GCC_PLUGINS_CFLAGS) $(SPARC_REG_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) # # vDSO code runs in userspace and -pg doesn't help with profiling anyway.
@@ -79,6 +79,7 @@ KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS)) KBUILD_CFLAGS_32 := $(filter-out -mcmodel=medlow,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(RANDSTRUCT_CFLAGS),$(KBUILD_CFLAGS_32)) +KBUILD_CFLAGS_32 := $(filter-out $(KSTACK_ERASE_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(SPARC_REG_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 += -m32 -msoft-float -fpic
arch/x86/entry/vdso/Makefile +2 -1
@@ -62,7 +62,7 @@ ifneq ($(RETPOLINE_VDSO_CFLAGS),) endif endif -$(vobjs): KBUILD_CFLAGS := $(filter-out $(PADDING_CFLAGS) $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) +$(vobjs): KBUILD_CFLAGS := $(filter-out $(PADDING_CFLAGS) $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) $(RANDSTRUCT_CFLAGS) $(KSTACK_ERASE_CFLAGS) $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) $(vobjs): KBUILD_AFLAGS += -DBUILD_VDSO #
@@ -123,6 +123,7 @@ KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(RANDSTRUCT_CFLAGS),$(KBUILD_CFLAGS_32)) +KBUILD_CFLAGS_32 := $(filter-out $(KSTACK_ERASE_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS_32))
scripts/Makefile.gcc-plugins +2 -14
@@ -8,20 +8,6 @@ ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY endif export DISABLE_LATENT_ENTROPY_PLUGIN -gcc-plugin-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak_plugin.so -gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ - += -DSTACKLEAK_PLUGIN -gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ - += -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_KSTACK_ERASE_TRACK_MIN_SIZE) -gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ - += -fplugin-arg-stackleak_plugin-arch=$(SRCARCH) -gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK_VERBOSE) \ - += -fplugin-arg-stackleak_plugin-verbose -ifdef CONFIG_GCC_PLUGIN_STACKLEAK - DISABLE_KSTACK_ERASE += -fplugin-arg-stackleak_plugin-disable -endif -export DISABLE_KSTACK_ERASE - # All the plugin CFLAGS are collected here in case a build target needs to # filter them out of the KBUILD_CFLAGS. GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) -DGCC_PLUGINS
@@ -34,6 +20,8 @@ KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) # be included in GCC_PLUGIN so they can get built. gcc-plugin-external-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) \ += randomize_layout_plugin.so +gcc-plugin-external-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ + += stackleak_plugin.so # All enabled GCC plugins are collected here for building in # scripts/gcc-scripts/Makefile.
scripts/Makefile.kstack_erase new file +15 -0
@@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 + +ifdef CONFIG_GCC_PLUGIN_STACKLEAK +kstack-erase-cflags-y += -fplugin=$(objtree)/scripts/gcc-plugins/stackleak_plugin.so +kstack-erase-cflags-y += -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_KSTACK_ERASE_TRACK_MIN_SIZE) +kstack-erase-cflags-y += -fplugin-arg-stackleak_plugin-arch=$(SRCARCH) +kstack-erase-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK_VERBOSE) += -fplugin-arg-stackleak_plugin-verbose +DISABLE_KSTACK_ERASE := -fplugin-arg-stackleak_plugin-disable +endif + +KSTACK_ERASE_CFLAGS := $(kstack-erase-cflags-y) + +export STACKLEAK_CFLAGS DISABLE_KSTACK_ERASE + +KBUILD_CFLAGS += $(KSTACK_ERASE_CFLAGS)
MAINTAINERS +2 -0
@@ -13181,6 +13181,8 @@ F: kernel/kstack_erase.c F: lib/tests/randstruct_kunit.c F: lib/tests/usercopy_kunit.c F: mm/usercopy.c +F: scripts/Makefile.kstack_erase +F: scripts/Makefile.randstruct F: security/Kconfig.hardening K: \b(add|choose)_random_kstack_offset\b K: \b__check_(object_size|heap_object)\b
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v3 4/13 x86: Handle KCOV __init vs inline mismatches
In reply to Kees CookWhen KCOV is enabled all functions get instrumented, unless the __no_sanitize_coverage attribute is used. To prepare for __no_sanitize_coverage being applied to __init functions, we have to handle differences in how GCC's inline optimizations get resolved. For x86 this means forcing several functions to be inline with __always_inline.
---
Cc: Thomas Gleixner <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: <[email protected]>
Cc: "H. Peter Anvin" <[email protected]>
Cc: Paolo Bonzini <[email protected]>
Cc: Vitaly Kuznetsov <[email protected]>
Cc: Henrique de Moraes Holschuh <[email protected]>
Cc: Hans de Goede <[email protected]>
Cc: "Ilpo Järvinen" <[email protected]>
Cc: "Rafael J. Wysocki" <[email protected]>
Cc: Len Brown <[email protected]>
Cc: Masami Hiramatsu <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: Michal Wilczynski <[email protected]>
Cc: Juergen Gross <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: "Kirill A. Shutemov" <[email protected]>
Cc: Roger Pau Monne <[email protected]>
Cc: David Woodhouse <[email protected]>
Cc: Usama Arif <[email protected]>
Cc: "Guilherme G. Piccoli" <[email protected]>
Cc: Thomas Huth <[email protected]>
Cc: Brian Gerst <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
--- arch/x86/include/asm/acpi.h | 4 ++-- arch/x86/include/asm/realmode.h | 2 +- include/linux/acpi.h | 4 ++-- include/linux/bootconfig.h | 2 +- include/linux/efi.h | 2 +- include/linux/memblock.h | 2 +- include/linux/smp.h | 2 +- arch/x86/kernel/kvm.c | 2 +- arch/x86/mm/init_64.c | 2 +- kernel/kexec_handover.c | 4 ++-- 10 files changed, 13 insertions(+), 13 deletions(-)
arch/x86/include/asm/acpi.h +2 -2
@@ -158,13 +158,13 @@ static inline bool acpi_has_cpu_in_madt(void) }#define ACPI_HAVE_ARCH_SET_ROOT_POINTER -static inline void acpi_arch_set_root_pointer (u64 addr) +static __always_inline void acpi_arch_set_root_pointer(u64 addr) { x86_init.acpi.set_root_pointer (addr); }#define ACPI_HAVE_ARCH_GET_ROOT_POINTER -static inline u64 acpi_arch_get_root_pointer (void ) +static __always_inline u64 acpi_arch_get_root_pointer(void) {return x86_init.acpi.get_root_pointer (); }
arch/x86/include/asm/realmode.h +1 -1
@@ -78,7 +78,7 @@ extern unsigned char secondary_startup_64[];extern unsigned char secondary_startup_64_no_verify[];#endif -static inline size_t real_mode_size_needed (void ) +static __always_inline size_t real_mode_size_needed(void) {if (real_mode_header)return 0 ;/* already allocated. */
include/linux/acpi.h +2 -2
@@ -759,13 +759,13 @@ int acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem, int *timer_count)#endif #ifndef ACPI_HAVE_ARCH_SET_ROOT_POINTER -static inline void acpi_arch_set_root_pointer (u64 addr) +static __always_inline void acpi_arch_set_root_pointer(u64 addr) { }#endif #ifndef ACPI_HAVE_ARCH_GET_ROOT_POINTER -static inline u64 acpi_arch_get_root_pointer (void ) +static __always_inline u64 acpi_arch_get_root_pointer(void) {return 0 ; }
include/linux/bootconfig.h +1 -1
@@ -290,7 +290,7 @@ int __init xbc_get_info(int *node_size, size_t *data_size);/* XBC cleanup data structures */ void __init _xbc_exit (bool early); -static inline void xbc_exit (void ) +static __always_inline void xbc_exit(void) {_xbc_exit (false); }
include/linux/efi.h +1 -1
@@ -1334,7 +1334,7 @@ struct linux_efi_initrd {bool xen_efi_config_table_is_usable (const efi_guid_t *guid,unsigned long table); -static inline +static __always_inline bool efi_config_table_is_usable(const efi_guid_t *guid, unsigned long table) {if (!IS_ENABLED (CONFIG_XEN_EFI ))
include/linux/memblock.h +1 -1
@@ -463,7 +463,7 @@ static inline void *memblock_alloc_raw(phys_addr_t size, NUMA_NO_NODE); } -static inline void *memblock_alloc_from (phys_addr_t size, +static __always_inline void *memblock_alloc_from(phys_addr_t size,phys_addr_t align,phys_addr_t min_addr) {
include/linux/smp.h +1 -1
@@ -221,7 +221,7 @@ static inline void wake_up_all_idle_cpus(void) { }#ifdef CONFIG_UP_LATE_INIT extern void __init up_late_init (void ); -static inline void smp_init (void ) {up_late_init (); } +static __always_inline void smp_init(void) { up_late_init(); }#else static inline void smp_init (void ) { }#endif
arch/x86/kernel/kvm.c +1 -1
@@ -420,7 +420,7 @@ static u64 kvm_steal_clock(int cpu)return steal; } -static inline void __set_percpu_decrypted (void *ptr,unsigned long size) +static inline __init void __set_percpu_decrypted (void *ptr,unsigned long size) {early_set_memory_decrypted ((unsigned long ) ptr, size); }
arch/x86/mm/init_64.c +1 -1
@@ -805,7 +805,7 @@ kernel_physical_mapping_change(unsigned long paddr_start, }#ifndef CONFIG_NUMA -static inline void x86_numa_init (void ) +static __always_inline void x86_numa_init(void) {memblock_set_node (0 ,PHYS_ADDR_MAX , &memblock.memory,0 ); }
kernel/kexec_handover.c +2 -2
@@ -310,8 +310,8 @@ static int kho_mem_serialize(struct kho_serialization *ser)return -ENOMEM ; } -static void deserialize_bitmap (unsigned int order, -struct khoser_mem_bitmap_ptr *elm) +static void __init deserialize_bitmap (unsigned int order, +struct khoser_mem_bitmap_ptr *elm) {struct kho_mem_phys_bits *bitmap =KHOSER_LOAD_PTR (elm->bitmap);unsigned long bit;
Signature · 1 line
2.34.1
Mike Rapoport
maintainerRe: [PATCH v3 04/13] x86: Handle KCOV __init vs inline mismatches
Hi Kees,
Quoted 8 lines · Kees Cook
When KCOV is enabled all functions get instrumented, unless the
__no_sanitize_coverageattribute is used. To prepare for__no_sanitize_coveragebeing applied to__initfunctions, we have to handle differences in how GCC's inline optimizations get resolved. For x86 this means forcing several functions to be inline with__always_inline.Signed-off-by Kees Cook <[email protected]>
...
include/linux/memblock.h static inline void *memblock_alloc_raw(phys_addr_t size, · line 468
Quoted 12 lines
include/linux/memblock.h +1
-1@@ -463,7 +463,7 @@ static inline void *memblock_alloc_raw(phys_addr_t size, NUMA_NO_NODE); } -static inline void *memblock_alloc_from (phys_addr_t size, +static __always_inline void *memblock_alloc_from(phys_addr_t size,phys_addr_t align,phys_addr_t min_addr)
I'm curious why from all memblock_alloc* wrappers this is the only one that needs to be __always_inline?
Signature · 2 lines
Sincerely yours, Mike.
Kees Cook
maintainerRe: [PATCH v3 04/13] x86: Handle KCOV __init vs inline mismatches
Quoted 22 lines · Mike Rapoport
Hi Kees,
Quoted 8 lines · Kees Cook
When KCOV is enabled all functions get instrumented, unless the
__no_sanitize_coverageattribute is used. To prepare for__no_sanitize_coveragebeing applied to__initfunctions, we have to handle differences in how GCC's inline optimizations get resolved. For x86 this means forcing several functions to be inline with__always_inline.Signed-off-by Kees Cook <[email protected]>...
Quoted 8 lines
include/linux/memblock.h +0
-0@@ -463,7 +463,7 @@ static inline void *memblock_alloc_raw(phys_addr_t size, NUMA_NO_NODE); }
Quoted 7 lines
include/linux/memblock.h static inline void *memblock_alloc_raw(phys_addr_t size, · line 468
Quoted 4 lines
include/linux/memblock.h +1
-1-static inline void *memblock_alloc_from (phys_addr_t size, +static __always_inline void *memblock_alloc_from(phys_addr_t size,phys_addr_t align,phys_addr_t min_addr)I'm curious why from all memblock_alloc* wrappers this is the only one that needs to be
__always_inline?
Thread-merge[1], adding Will Deacon, who was kind of asking the same question.
Based on what I can tell, GCC has kind of fragile inlining logic, in the sense that it can change whether or not it inlines something based on optimizations. It looks like the kcov instrumentation being added (or in this case, removed) from a function changes the optimization results, and some functions marked "inline" are _not_ inlined. In that case, we end up with __init code calling a function not marked __init, and we get the build warnings I'm trying to eliminate.
So, to Will's comment, yes, the problem is somewhat fragile (though using either __always_inline or __init will deterministically solve it). We've tripped over this before with GCC and the solution has usually been to just use __always_inline and move on.
For memblock_alloc*, it appears to be that the heuristic GCC uses resulted in only memblock_alloc_from() being a problem in this case. I can certainly mark them all as __always_inline if that is preferred.
Some maintainers have wanted things marked __init, some have wanted __always_inline. I opted for __always_inline since that was basically the intent of marking a function "inline" in the first place. I am happy to do whatever. :)
-Kees
[1] https://lore.kernel.org/lkml/aHouXI5-tyQw78Ht@willie-the-truck/
Signature · 1 line
Kees Cook
Ard Biesheuvel
maintainerRe: [PATCH v3 04/13] x86: Handle KCOV __init vs inline mismatches
Quoted 43 lines · Kees Cook
Quoted 22 lines · Mike Rapoport
Hi Kees,
Quoted 8 lines · Kees Cook
When KCOV is enabled all functions get instrumented, unless the
__no_sanitize_coverageattribute is used. To prepare for__no_sanitize_coveragebeing applied to__initfunctions, we have to handle differences in how GCC's inline optimizations get resolved. For x86 this means forcing several functions to be inline with__always_inline.Signed-off-by Kees Cook <[email protected]>...
Quoted 8 lines
include/linux/memblock.h +0
-0@@ -463,7 +463,7 @@ static inline void *memblock_alloc_raw(phys_addr_t size, NUMA_NO_NODE); }Quoted 7 lines
include/linux/memblock.h static inline void *memblock_alloc_raw(phys_addr_t size, · line 468
Quoted 4 lines
include/linux/memblock.h +1
-1-static inline void *memblock_alloc_from (phys_addr_t size, +static __always_inline void *memblock_alloc_from(phys_addr_t size,phys_addr_t align,phys_addr_t min_addr)I'm curious why from all memblock_alloc* wrappers this is the only one that needs to be
__always_inline?Thread-merge[1], adding Will Deacon, who was kind of asking the same question.
Based on what I can tell, GCC has kind of fragile inlining logic, in the sense that it can change whether or not it inlines something based on optimizations. It looks like the kcov instrumentation being added (or in this case, removed) from a function changes the optimization results, and some functions marked "inline" are _not_ inlined. In that case, we end up with
__initcode calling a function not marked__init, and we get the build warnings I'm trying to eliminate.
Quoted 5 lines
So, to Will's comment, yes, the problem is somewhat fragile (though using either
__always_inlineor__initwill deterministically solve it). We've tripped over this before with GCC and the solution has usually been to just use__always_inlineand move on.
Given that 'inline' is already a macro in the kernel, could we just add __attribute__((__always_inline__)) to it when KCOV is enabled?
Will Deacon
maintainerRe: [PATCH v3 04/13] x86: Handle KCOV __init vs inline mismatches
Quoted 33 lines · Ard Biesheuvel
Quoted 32 lines · Kees Cook
Quoted 20 lines · Mike Rapoport
Quoted 8 lines · Kees Cook
When KCOV is enabled all functions get instrumented, unless the
__no_sanitize_coverageattribute is used. To prepare for__no_sanitize_coveragebeing applied to__initfunctions, we have to handle differences in how GCC's inline optimizations get resolved. For x86 this means forcing several functions to be inline with__always_inline.Signed-off-by Kees Cook <[email protected]>...
Quoted 8 lines
include/linux/memblock.h +0
-0@@ -463,7 +463,7 @@ static inline void *memblock_alloc_raw(phys_addr_t size, NUMA_NO_NODE); }Quoted 7 lines
include/linux/memblock.h static inline void *memblock_alloc_raw(phys_addr_t size, · line 468
Quoted 4 lines
include/linux/memblock.h +1
-1-static inline void *memblock_alloc_from (phys_addr_t size, +static __always_inline void *memblock_alloc_from(phys_addr_t size,phys_addr_t align,phys_addr_t min_addr)I'm curious why from all memblock_alloc* wrappers this is the only one that needs to be
__always_inline?Thread-merge[1], adding Will Deacon, who was kind of asking the same question.
Quoted 7 lines
Quoted 7 lines
Based on what I can tell, GCC has kind of fragile inlining logic, in the sense that it can change whether or not it inlines something based on optimizations. It looks like the kcov instrumentation being added (or in this case, removed) from a function changes the optimization results, and some functions marked "inline" are _not_ inlined. In that case, we end up with
__initcode calling a function not marked__init, and we get the build warnings I'm trying to eliminate.
Got it, thanks for the explanation!
Quoted 8 lines
Quoted 5 lines
So, to Will's comment, yes, the problem is somewhat fragile (though using either
__always_inlineor__initwill deterministically solve it). We've tripped over this before with GCC and the solution has usually been to just use__always_inlineand move on.Given that 'inline' is already a macro in the kernel, could we just add __attribute__((__always_inline__)) to it when KCOV is enabled?
That sounds like a more robust approach and, by the sounds of it, we could predicate it on GCC too. That would also provide a neat place for a comment describing the problem.
Kees, would that work for you?
Will
Kees Cook
maintainerRe: [PATCH v3 04/13] x86: Handle KCOV __init vs inline mismatches
Quoted 50 lines · Will Deacon
Quoted 33 lines · Ard Biesheuvel
Quoted 32 lines · Kees Cook
Quoted 20 lines · Mike Rapoport
Quoted 8 lines · Kees Cook
When KCOV is enabled all functions get instrumented, unless the
__no_sanitize_coverageattribute is used. To prepare for__no_sanitize_coveragebeing applied to__initfunctions, we have to handle differences in how GCC's inline optimizations get resolved. For x86 this means forcing several functions to be inline with__always_inline.Signed-off-by Kees Cook <[email protected]>...
Quoted 8 lines
include/linux/memblock.h +0
-0@@ -463,7 +463,7 @@ static inline void *memblock_alloc_raw(phys_addr_t size, NUMA_NO_NODE); }Quoted 7 lines
include/linux/memblock.h static inline void *memblock_alloc_raw(phys_addr_t size, · line 468
Quoted 4 lines
include/linux/memblock.h +1
-1-static inline void *memblock_alloc_from (phys_addr_t size, +static __always_inline void *memblock_alloc_from(phys_addr_t size,phys_addr_t align,phys_addr_t min_addr)I'm curious why from all memblock_alloc* wrappers this is the only one that needs to be
__always_inline?Thread-merge[1], adding Will Deacon, who was kind of asking the same question.
Quoted 7 lines
Quoted 7 lines
Based on what I can tell, GCC has kind of fragile inlining logic, in the sense that it can change whether or not it inlines something based on optimizations. It looks like the kcov instrumentation being added (or in this case, removed) from a function changes the optimization results, and some functions marked "inline" are _not_ inlined. In that case, we end up with
__initcode calling a function not marked__init, and we get the build warnings I'm trying to eliminate.Got it, thanks for the explanation!
Quoted 6 lines
Quoted 5 lines
So, to Will's comment, yes, the problem is somewhat fragile (though using either
__always_inlineor__initwill deterministically solve it). We've tripped over this before with GCC and the solution has usually been to just use__always_inlineand move on.
Quoted 8 lines
Quoted 2 lines
Given that 'inline' is already a macro in the kernel, could we just add __attribute__((__always_inline__)) to it when KCOV is enabled?
That sounds like a more robust approach and, by the sounds of it, we could predicate it on GCC too. That would also provide a neat place for a comment describing the problem.
Kees, would that work for you?
That seems like an extremely large hammer for this problem, IMO. It feels like it could cause new strange corner cases. I'd much prefer the small fixes I've currently got since it keeps it focused. KCOV is already enabled for "allmodconfig", so any new instances would be found very quickly, etc. (And GCC's fragility in this regard has already been exposed to these cases -- it's just that I changed one of the combinations of __init vs inline vs instrumentation.
I could give it a try, if you really prefer the big hammer approach...
Signature · 1 line
Kees Cook
Kees Cook
maintainerRe: [PATCH v3 04/13] x86: Handle KCOV __init vs inline mismatches
Quoted 68 lines · Kees Cook
Quoted 50 lines · Will Deacon
Quoted 33 lines · Ard Biesheuvel
Quoted 32 lines · Kees Cook
Quoted 20 lines · Mike Rapoport
Quoted 8 lines · Kees Cook
When KCOV is enabled all functions get instrumented, unless the
__no_sanitize_coverageattribute is used. To prepare for__no_sanitize_coveragebeing applied to__initfunctions, we have to handle differences in how GCC's inline optimizations get resolved. For x86 this means forcing several functions to be inline with__always_inline.Signed-off-by Kees Cook <[email protected]>...
Quoted 8 lines
include/linux/memblock.h +0
-0@@ -463,7 +463,7 @@ static inline void *memblock_alloc_raw(phys_addr_t size, NUMA_NO_NODE); }Quoted 7 lines
include/linux/memblock.h static inline void *memblock_alloc_raw(phys_addr_t size, · line 468
Quoted 4 lines
include/linux/memblock.h +1
-1-static inline void *memblock_alloc_from (phys_addr_t size, +static __always_inline void *memblock_alloc_from(phys_addr_t size,phys_addr_t align,phys_addr_t min_addr)I'm curious why from all memblock_alloc* wrappers this is the only one that needs to be
__always_inline?Thread-merge[1], adding Will Deacon, who was kind of asking the same question.
Quoted 7 lines
Quoted 7 lines
Based on what I can tell, GCC has kind of fragile inlining logic, in the sense that it can change whether or not it inlines something based on optimizations. It looks like the kcov instrumentation being added (or in this case, removed) from a function changes the optimization results, and some functions marked "inline" are _not_ inlined. In that case, we end up with
__initcode calling a function not marked__init, and we get the build warnings I'm trying to eliminate.Got it, thanks for the explanation!
Quoted 6 lines
Quoted 5 lines
So, to Will's comment, yes, the problem is somewhat fragile (though using either
__always_inlineor__initwill deterministically solve it). We've tripped over this before with GCC and the solution has usually been to just use__always_inlineand move on.Quoted 8 lines
Quoted 2 lines
Given that 'inline' is already a macro in the kernel, could we just add __attribute__((__always_inline__)) to it when KCOV is enabled?
That sounds like a more robust approach and, by the sounds of it, we could predicate it on GCC too. That would also provide a neat place for a comment describing the problem.
Kees, would that work for you?
That seems like an extremely large hammer for this problem, IMO. It feels like it could cause new strange corner cases. I'd much prefer the small fixes I've currently got since it keeps it focused. KCOV is already enabled for "allmodconfig", so any new instances would be found very quickly, etc. (And GCC's fragility in this regard has already been exposed to these cases -- it's just that I changed one of the combinations of
__initvs inline vs instrumentation.
Quoted 1 line
I could give it a try, if you really prefer the big hammer approach...
I gave it a try -- it fails spectacularly. ;) Let's stick to my small fixes instead?
Signature · 1 line
Kees Cook
Ard Biesheuvel
maintainerRe: [PATCH v3 04/13] x86: Handle KCOV __init vs inline mismatches
Quoted 70 lines · Kees Cook
Quoted 68 lines · Kees Cook
Quoted 50 lines · Will Deacon
Quoted 33 lines · Ard Biesheuvel
Quoted 32 lines · Kees Cook
Quoted 20 lines · Mike Rapoport
Quoted 8 lines · Kees Cook
When KCOV is enabled all functions get instrumented, unless the
__no_sanitize_coverageattribute is used. To prepare for__no_sanitize_coveragebeing applied to__initfunctions, we have to handle differences in how GCC's inline optimizations get resolved. For x86 this means forcing several functions to be inline with__always_inline.Signed-off-by Kees Cook <[email protected]>...
Quoted 8 lines
include/linux/memblock.h +0
-0@@ -463,7 +463,7 @@ static inline void *memblock_alloc_raw(phys_addr_t size, NUMA_NO_NODE); }Quoted 7 lines
include/linux/memblock.h static inline void *memblock_alloc_raw(phys_addr_t size, · line 468
Quoted 4 lines
include/linux/memblock.h +1
-1-static inline void *memblock_alloc_from (phys_addr_t size, +static __always_inline void *memblock_alloc_from(phys_addr_t size,phys_addr_t align,phys_addr_t min_addr)I'm curious why from all memblock_alloc* wrappers this is the only one that needs to be
__always_inline?Thread-merge[1], adding Will Deacon, who was kind of asking the same question.
Quoted 7 lines
Quoted 7 lines
Based on what I can tell, GCC has kind of fragile inlining logic, in the sense that it can change whether or not it inlines something based on optimizations. It looks like the kcov instrumentation being added (or in this case, removed) from a function changes the optimization results, and some functions marked "inline" are _not_ inlined. In that case, we end up with
__initcode calling a function not marked__init, and we get the build warnings I'm trying to eliminate.Got it, thanks for the explanation!
Quoted 6 lines
Quoted 5 lines
So, to Will's comment, yes, the problem is somewhat fragile (though using either
__always_inlineor__initwill deterministically solve it). We've tripped over this before with GCC and the solution has usually been to just use__always_inlineand move on.Quoted 8 lines
Quoted 2 lines
Given that 'inline' is already a macro in the kernel, could we just add __attribute__((__always_inline__)) to it when KCOV is enabled?
That sounds like a more robust approach and, by the sounds of it, we could predicate it on GCC too. That would also provide a neat place for a comment describing the problem.
Kees, would that work for you?
That seems like an extremely large hammer for this problem, IMO. It feels like it could cause new strange corner cases. I'd much prefer the small fixes I've currently got since it keeps it focused. KCOV is already enabled for "allmodconfig", so any new instances would be found very quickly, etc. (And GCC's fragility in this regard has already been exposed to these cases -- it's just that I changed one of the combinations of
__initvs inline vs instrumentation.
Quoted 5 lines
Quoted 1 line
I could give it a try, if you really prefer the big hammer approach...
I gave it a try -- it fails spectacularly. ;) Let's stick to my small fixes instead?
Fair enough :-)
Will Deacon
maintainerRe: [PATCH v3 04/13] x86: Handle KCOV __init vs inline mismatches
Quoted 71 lines · Ard Biesheuvel
Quoted 70 lines · Kees Cook
Quoted 68 lines · Kees Cook
Quoted 50 lines · Will Deacon
Quoted 33 lines · Ard Biesheuvel
Quoted 32 lines · Kees Cook
Quoted 20 lines · Mike Rapoport
Quoted 8 lines · Kees Cook
When KCOV is enabled all functions get instrumented, unless the
__no_sanitize_coverageattribute is used. To prepare for__no_sanitize_coveragebeing applied to__initfunctions, we have to handle differences in how GCC's inline optimizations get resolved. For x86 this means forcing several functions to be inline with__always_inline.Signed-off-by Kees Cook <[email protected]>...
Quoted 8 lines
include/linux/memblock.h +0
-0@@ -463,7 +463,7 @@ static inline void *memblock_alloc_raw(phys_addr_t size, NUMA_NO_NODE); }Quoted 7 lines
include/linux/memblock.h static inline void *memblock_alloc_raw(phys_addr_t size, · line 468
Quoted 4 lines
include/linux/memblock.h +1
-1-static inline void *memblock_alloc_from (phys_addr_t size, +static __always_inline void *memblock_alloc_from(phys_addr_t size,phys_addr_t align,phys_addr_t min_addr)I'm curious why from all memblock_alloc* wrappers this is the only one that needs to be
__always_inline?Thread-merge[1], adding Will Deacon, who was kind of asking the same question.
Quoted 7 lines
Quoted 7 lines
Based on what I can tell, GCC has kind of fragile inlining logic, in the sense that it can change whether or not it inlines something based on optimizations. It looks like the kcov instrumentation being added (or in this case, removed) from a function changes the optimization results, and some functions marked "inline" are _not_ inlined. In that case, we end up with
__initcode calling a function not marked__init, and we get the build warnings I'm trying to eliminate.Got it, thanks for the explanation!
Quoted 6 lines
Quoted 5 lines
So, to Will's comment, yes, the problem is somewhat fragile (though using either
__always_inlineor__initwill deterministically solve it). We've tripped over this before with GCC and the solution has usually been to just use__always_inlineand move on.Quoted 8 lines
Quoted 2 lines
Given that 'inline' is already a macro in the kernel, could we just add __attribute__((__always_inline__)) to it when KCOV is enabled?
That sounds like a more robust approach and, by the sounds of it, we could predicate it on GCC too. That would also provide a neat place for a comment describing the problem.
Kees, would that work for you?
That seems like an extremely large hammer for this problem, IMO. It feels like it could cause new strange corner cases. I'd much prefer the small fixes I've currently got since it keeps it focused. KCOV is already enabled for "allmodconfig", so any new instances would be found very quickly, etc. (And GCC's fragility in this regard has already been exposed to these cases -- it's just that I changed one of the combinations of
__initvs inline vs instrumentation.
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
I could give it a try, if you really prefer the big hammer approach...
I gave it a try -- it fails spectacularly. ;) Let's stick to my small fixes instead?
Fair enough :-)
(but please add the helpful explanation you provided to the commit message!)
Will
Mike Rapoport
maintainerRe: [PATCH v3 04/13] x86: Handle KCOV __init vs inline mismatches
In reply to Kees CookQuoted 42 lines · Kees Cook
Quoted 22 lines · Mike Rapoport
Hi Kees,
Quoted 8 lines · Kees Cook
When KCOV is enabled all functions get instrumented, unless the
__no_sanitize_coverageattribute is used. To prepare for__no_sanitize_coveragebeing applied to__initfunctions, we have to handle differences in how GCC's inline optimizations get resolved. For x86 this means forcing several functions to be inline with__always_inline.Signed-off-by Kees Cook <[email protected]>...
Quoted 8 lines
include/linux/memblock.h +0
-0@@ -463,7 +463,7 @@ static inline void *memblock_alloc_raw(phys_addr_t size, NUMA_NO_NODE); }Quoted 7 lines
include/linux/memblock.h static inline void *memblock_alloc_raw(phys_addr_t size, · line 468
Quoted 4 lines
include/linux/memblock.h +1
-1-static inline void *memblock_alloc_from (phys_addr_t size, +static __always_inline void *memblock_alloc_from(phys_addr_t size,phys_addr_t align,phys_addr_t min_addr)I'm curious why from all memblock_alloc* wrappers this is the only one that needs to be
__always_inline?Thread-merge[1], adding Will Deacon, who was kind of asking the same question.
Based on what I can tell, GCC has kind of fragile inlining logic, in the sense that it can change whether or not it inlines something based on optimizations. It looks like the kcov instrumentation being added (or in this case, removed) from a function changes the optimization results, and some functions marked "inline" are _not_ inlined. In that case, we end up with
__initcode calling a function not marked__init, and we get the build warnings I'm trying to eliminate.
Quoted 8 lines
So, to Will's comment, yes, the problem is somewhat fragile (though using either
__always_inlineor__initwill deterministically solve it). We've tripped over this before with GCC and the solution has usually been to just use__always_inlineand move on.For memblock_alloc*, it appears to be that the heuristic GCC uses resulted in only
memblock_alloc_from()being a problem in this case. I can certainly mark them all as__always_inlineif that is preferred.
We had a few of those already converted to __always_inline, so I'm ok with continuing to fix them one at at time. Gives a feeling of job security ;-)
Quoted 2 lines
Signature · 1 line
Kees Cook
Signature · 2 lines
Sincerely yours, Mike.
Kees Cook
maintainerPATCH v3 5/13 arm: Handle KCOV __init vs inline mismatches
In reply to Kees CookWhen KCOV is enabled all functions get instrumented, unless the __no_sanitize_coverage attribute is used. To prepare for __no_sanitize_coverage being applied to __init functions, we have to handle differences in how GCC's inline optimizations get resolved. For arm this exposed several places where __init annotations were missing but ended up being "accidentally correct". Fix these cases and force several functions to be inline with __always_inline.
---
Cc: Russell King <[email protected]>
Cc: Daniel Lezcano <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Nishanth Menon <[email protected]>
Cc: Santosh Shilimkar <[email protected]>
Cc: Lee Jones <[email protected]>
Cc: Allison Randal <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: <[email protected]>
--- include/linux/mfd/dbx500-prcmu.h | 2 +- arch/arm/mm/cache-feroceon-l2.c | 2 +- arch/arm/mm/cache-tauros2.c | 2 +- drivers/clocksource/timer-orion.c | 2 +- drivers/soc/ti/pm33xx.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-)
include/linux/mfd/dbx500-prcmu.h +1 -1
@@ -213,7 +213,7 @@ struct prcmu_fw_version {#if defined(CONFIG_UX500_SOC_DB8500 ) -static inline void prcmu_early_init (void ) +static inline void __init prcmu_early_init (void ) {db8500_prcmu_early_init (); }
arch/arm/mm/cache-feroceon-l2.c +1 -1
@@ -295,7 +295,7 @@ static inline u32 read_extra_features(void)return u; } -static inline void write_extra_features (u32 u) +static inline void __init write_extra_features (u32 u) { __asm__("mcr p15, 1, %0, c15, c1, 0" : :"r" (u)); }
arch/arm/mm/cache-tauros2.c +1 -1
@@ -177,7 +177,7 @@ static inline void __init write_actlr(u32 actlr) __asm__("mcr p15, 0, %0, c1, c0, 1\n" : :"r" (actlr)); } -static void enable_extra_feature (unsigned int features) +static void __init enable_extra_feature (unsigned int features) {u32 u;
drivers/clocksource/timer-orion.c +1 -1
@@ -43,7 +43,7 @@ static struct delay_timer orion_delay_timer = { .read_current_timer = orion_read_timer, }; -static void orion_delay_timer_init (unsigned long rate) +static void __init orion_delay_timer_init (unsigned long rate) { orion_delay_timer.freq = rate;register_current_timer_delay (&orion_delay_timer);
drivers/soc/ti/pm33xx.c +1 -1
@@ -145,7 +145,7 @@ static int am33xx_do_sram_idle(u32 wfi_flags)return pm_ops->cpu_suspend (am33xx_do_wfi_sram, wfi_flags); } -static int __init am43xx_map_gic (void ) +static int am43xx_map_gic (void ) { gic_dist_base =ioremap (AM43XX_GIC_DIST_BASE ,SZ_4K );
Signature · 1 line
2.34.1
Re: [PATCH v3 05/13] arm: Handle KCOV __init vs inline mismatches
Quoted 8 lines · Kees Cook
When KCOV is enabled all functions get instrumented, unless the
__no_sanitize_coverageattribute is used. To prepare for__no_sanitize_coveragebeing applied to__initfunctions, we have to handle differences in how GCC's inline optimizations get resolved. For arm this exposed several places where__initannotations were missing but ended up being "accidentally correct". Fix these cases and force several functions to be inline with__always_inline.
[..]
drivers/soc/ti/pm33xx.c static int am33xx_do_sram_idle(u32 wfi_flags) · line 150
Quoted 12 lines
drivers/soc/ti/pm33xx.c +1
-1@@ -145,7 +145,7 @@ static int am33xx_do_sram_idle(u32 wfi_flags)return pm_ops->cpu_suspend (am33xx_do_wfi_sram, wfi_flags); } -static int __init am43xx_map_gic (void ) +static int am43xx_map_gic (void ) { gic_dist_base =ioremap (AM43XX_GIC_DIST_BASE ,SZ_4K );
Signature · 4 lines
Regards, Nishanth Menon Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3 1A34 DDB5 849D 1736 249D https://ti.com/opensource
Re: [PATCH v3 05/13] arm: Handle KCOV __init vs inline mismatches
In reply to Kees CookQuoted 20 lines · Kees Cook
When KCOV is enabled all functions get instrumented, unless the
__no_sanitize_coverageattribute is used. To prepare for__no_sanitize_coveragebeing applied to__initfunctions, we have to handle differences in how GCC's inline optimizations get resolved. For arm this exposed several places where__initannotations were missing but ended up being "accidentally correct". Fix these cases and force several functions to be inline with__always_inline.Acked-by Nishanth Menon <[email protected]>Signed-off-by Kees Cook <[email protected]>---
Cc: Russell King <[email protected]>
Cc: Daniel Lezcano <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Nishanth Menon <[email protected]>
Cc: Santosh Shilimkar <[email protected]>
Cc: Lee Jones <[email protected]>
Cc: Allison Randal <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: <[email protected]>
Quoted 2 lines
--- include/linux/mfd/dbx500-prcmu.h | 2 +-
Quoted 74 lines
arch/arm/mm/cache-feroceon-l2.c | 2 +- arch/arm/mm/cache-tauros2.c | 2 +- drivers/clocksource/timer-orion.c | 2 +- drivers/soc/ti/pm33xx.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-)include/linux/mfd/dbx500-prcmu.h +1
-1@@ -213,7 +213,7 @@ struct prcmu_fw_version {#if defined(CONFIG_UX500_SOC_DB8500 ) -static inline void prcmu_early_init (void ) +static inline void __init prcmu_early_init (void ) {db8500_prcmu_early_init (); }arch/arm/mm/cache-feroceon-l2.c +1
-1@@ -295,7 +295,7 @@ static inline u32 read_extra_features(void)return u; } -static inline void write_extra_features (u32 u) +static inline void __init write_extra_features (u32 u) { __asm__("mcr p15, 1, %0, c15, c1, 0" : :"r" (u)); }arch/arm/mm/cache-tauros2.c +1
-1@@ -177,7 +177,7 @@ static inline void __init write_actlr(u32 actlr) __asm__("mcr p15, 0, %0, c1, c0, 1\n" : :"r" (actlr)); } -static void enable_extra_feature (unsigned int features) +static void __init enable_extra_feature (unsigned int features) {u32 u;drivers/clocksource/timer-orion.c +1
-1@@ -43,7 +43,7 @@ static struct delay_timer orion_delay_timer = { .read_current_timer = orion_read_timer, }; -static void orion_delay_timer_init (unsigned long rate) +static void __init orion_delay_timer_init (unsigned long rate) { orion_delay_timer.freq = rate;register_current_timer_delay (&orion_delay_timer);drivers/soc/ti/pm33xx.c +1
-1@@ -145,7 +145,7 @@ static int am33xx_do_sram_idle(u32 wfi_flags)return pm_ops->cpu_suspend (am33xx_do_wfi_sram, wfi_flags); } -static int __init am43xx_map_gic (void ) +static int am43xx_map_gic (void ) { gic_dist_base =ioremap (AM43XX_GIC_DIST_BASE ,SZ_4K );Signature · 1 line
2.34.1
Signature · 1 line
Lee Jones [李琼斯]
Kees Cook
maintainerPATCH v3 6/13 arm64: Handle KCOV __init vs inline mismatches
In reply to Kees CookWhen KCOV is enabled all functions get instrumented, unless the __no_sanitize_coverage attribute is used. To prepare for __no_sanitize_coverage being applied to __init functions, we have to handle differences in how GCC's inline optimizations get resolved. For arm64 this requires forcing one function to be inline with __always_inline.
---
Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Jonathan Cameron <[email protected]>
Cc: Gavin Shan <[email protected]>
Cc: "Russell King (Oracle)" <[email protected]>
Cc: James Morse <[email protected]>
Cc: Oza Pawandeep <[email protected]>
Cc: Anshuman Khandual <[email protected]>
Cc: <[email protected]>
--- arch/arm64/include/asm/acpi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/include/asm/acpi.h +1 -1
@@ -150,7 +150,7 @@ acpi_set_mailbox_entry(int cpu, struct acpi_madt_generic_interrupt *processor) {}#endif -static inline const char *acpi_get_enable_method (int cpu) +static __always_inline const char *acpi_get_enable_method(int cpu) {if (acpi_psci_present ())return "psci" ;
Signature · 1 line
2.34.1
Will Deacon
maintainerRe: [PATCH v3 06/13] arm64: Handle KCOV __init vs inline mismatches
Hey Kees,
Quoted 6 lines · Kees Cook
When KCOV is enabled all functions get instrumented, unless the
__no_sanitize_coverageattribute is used. To prepare for__no_sanitize_coveragebeing applied to__initfunctions, we have to handle differences in how GCC's inline optimizations get resolved. For arm64 this requires forcing one function to be inline with__always_inline.
Please can you spell out the issue a bit more here? From the description you've given, I can't figure out why acpi_get_enable_method() is the only function that needs fixing up so I worry that this could be fragile.
Thanks,
Will
Kees Cook
maintainerPATCH v3 7/13 s390: Handle KCOV __init vs inline mismatches
In reply to Kees CookWhen KCOV is enabled all functions get instrumented, unless the __no_sanitize_coverage attribute is used. To prepare for __no_sanitize_coverage being applied to __init functions, we have to handle differences in how GCC's inline optimizations get resolved. For s390 this exposed a place where the __init annotation was missing but ended up being "accidentally correct". Fix this cases and force a couple functions to be inline with __always_inline.
---
Cc: Heiko Carstens <[email protected]>
Cc: Vasily Gorbik <[email protected]>
Cc: Alexander Gordeev <[email protected]>
Cc: Christian Borntraeger <[email protected]>
Cc: Sven Schnelle <[email protected]>
Cc: Gerald Schaefer <[email protected]>
Cc: Gaosheng Cui <[email protected]>
Cc: <[email protected]>
--- arch/s390/hypfs/hypfs.h | 2 +- arch/s390/hypfs/hypfs_diag.h | 2 +- arch/s390/mm/init.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
arch/s390/hypfs/hypfs.h +1 -1
@@ -48,7 +48,7 @@ void hypfs_sprp_exit(void);int __hypfs_fs_init (void ); -static inline int hypfs_fs_init (void ) +static __always_inline int hypfs_fs_init(void) {if (IS_ENABLED (CONFIG_S390_HYPFS_FS ))return __hypfs_fs_init ();
arch/s390/hypfs/hypfs_diag.h +1 -1
@@ -19,7 +19,7 @@ int diag204_store(void *buf, int pages);int __hypfs_diag_fs_init (void );void __hypfs_diag_fs_exit (void ); -static inline int hypfs_diag_fs_init (void ) +static __always_inline int hypfs_diag_fs_init(void) {if (IS_ENABLED (CONFIG_S390_HYPFS_FS ))return __hypfs_diag_fs_init ();
arch/s390/mm/init.c +1 -1
@@ -142,7 +142,7 @@ bool force_dma_unencrypted(struct device *dev) }/* protected virtualization */ -static void pv_init (void ) +static void __init pv_init (void ) {if (!is_prot_virt_guest ())return ;
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v3 8/13 powerpc/mm/book3s64: Move kfence and debug_pagealloc related calls to __init section
In reply to Kees CookFrom: "Ritesh Harjani (IBM)" <[email protected]>
Move a few kfence and debug_pagealloc related functions in hash_utils.c and radix_pgtable.c to __init sections since these are only invoked once by an __init function during system initialization.
i.e.
- hash_debug_pagealloc_alloc_slots()
- hash_kfence_alloc_pool()
- hash_kfence_map_pool()
The above 3 functions only gets called by __init htab_initialize().
- alloc_kfence_pool()
- map_kfence_pool()
The above 2 functions only gets called by __init radix_init_pgtable()
This should also help fix warning msgs like:
Quoted 1 line
Quoted 1 line
WARNING: modpost: vmlinux: section mismatch in reference:
hash_debug_pagealloc_alloc_slots+0xb0 (section: .text) -> memblock_alloc_try_nid (section: .init.text)
--- arch/powerpc/mm/book3s64/hash_utils.c | 6 +++--- arch/powerpc/mm/book3s64/radix_pgtable.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-)
arch/powerpc/mm/book3s64/hash_utils.c +3 -3
@@ -343,7 +343,7 @@ static inline bool hash_supports_debug_pagealloc(void)static u8 *linear_map_hash_slots;static unsigned long linear_map_hash_count;static DEFINE_RAW_SPINLOCK (linear_map_hash_lock); -static void hash_debug_pagealloc_alloc_slots (void ) +static __init void hash_debug_pagealloc_alloc_slots (void ) {if (!hash_supports_debug_pagealloc ())return ;
@@ -409,7 +409,7 @@ static DEFINE_RAW_SPINLOCK(linear_map_kf_hash_lock);static phys_addr_t kfence_pool; -static inline void hash_kfence_alloc_pool (void ) +static __init void hash_kfence_alloc_pool (void ) {if (!kfence_early_init_enabled ()) goto err;
@@ -445,7 +445,7 @@ static inline void hash_kfence_alloc_pool(void)disable_kfence (); } -static inline void hash_kfence_map_pool (void ) +static __init void hash_kfence_map_pool (void ) {unsigned long kfence_pool_start, kfence_pool_end;unsigned long prot =pgprot_val (PAGE_KERNEL );
arch/powerpc/mm/book3s64/radix_pgtable.c +2 -2
@@ -363,7 +363,7 @@ static int __meminit create_physical_mapping(unsigned long start, }#ifdef CONFIG_KFENCE -static inline phys_addr_t alloc_kfence_pool (void ) +static __init phys_addr_t alloc_kfence_pool (void ) {phys_addr_t kfence_pool;
@@ -393,7 +393,7 @@ static inline phys_addr_t alloc_kfence_pool(void)return 0 ; } -static inline void map_kfence_pool (phys_addr_t kfence_pool) +static __init void map_kfence_pool (phys_addr_t kfence_pool) {if (!kfence_pool)return ;
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v3 9/13 mips: Handle KCOV __init vs inline mismatch
In reply to Kees CookWhen KCOV is enabled all functions get instrumented, unless the __no_sanitize_coverage attribute is used. To prepare for __no_sanitize_coverage being applied to __init functions, we have to handle differences in how GCC's inline optimizations get resolved. For mips this requires adding the __init annotation on init_mips_clocksource().
---
Cc: Thomas Bogendoerfer <[email protected]>
Cc: <[email protected]>
--- arch/mips/include/asm/time.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/include/asm/time.h +1 -1
@@ -55,7 +55,7 @@ static inline int mips_clockevent_init(void)*/ extern int init_r4k_clocksource (void ); -static inline int init_mips_clocksource (void ) +static inline __init int init_mips_clocksource (void ) {#ifdef CONFIG_CSRC_R4K return init_r4k_clocksource ();
Signature · 1 line
2.34.1
Re: [PATCH v3 09/13] mips: Handle KCOV __init vs inline mismatch
Quoted 33 lines · Kees Cook
When KCOV is enabled all functions get instrumented, unless the
__no_sanitize_coverageattribute is used. To prepare for__no_sanitize_coveragebeing applied to__initfunctions, we have to handle differences in how GCC's inline optimizations get resolved. For mips this requires adding the__initannotation oninit_mips_clocksource().Signed-off-by Kees Cook <[email protected]>---
Cc: Thomas Bogendoerfer <[email protected]>
Cc: <[email protected]>--- arch/mips/include/asm/time.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)arch/mips/include/asm/time.h +1
-2@@ -55,7 +55,7 @@ static inline int mips_clockevent_init(void)*/ extern int init_r4k_clocksource (void ); -static inline int init_mips_clocksource (void ) +static inline __init int init_mips_clocksource (void ) {#ifdef CONFIG_CSRC_R4K return init_r4k_clocksource (); --2.34.1
Kees Cook
maintainerPATCH v3 10/13 init.h: Disable sanitizer coverage for __init and __head
In reply to Kees CookWhile __noinstr already contained __no_sanitize_coverage, it needs to be added to __init and __head section markings to support the Clang implementation of CONFIG_KSTACK_ERASE. This is to make sure the stack depth tracking callback is not executed in unsupported contexts.
The other sanitizer coverage options (trace-pc and trace-cmp) aren't needed in __head nor __init either ("We are interested in code coverage as a function of a syscall inputs"[1]), so this is fine to disable for them as well.
---
Cc: Marco Elver <[email protected]>
Cc: Andrey Konovalov <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: <[email protected]>
Cc: "H. Peter Anvin" <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
Cc: "Kirill A. Shutemov" <[email protected]>
Cc: Hou Wenlong <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: "Peter Zijlstra (Intel)" <[email protected]>
Cc: Luis Chamberlain <[email protected]>
Cc: Sami Tolvanen <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Christophe Leroy <[email protected]>
Cc: <[email protected]>
--- arch/x86/include/asm/init.h | 2 +- include/linux/init.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-)
arch/x86/include/asm/init.h +1 -1
@@ -5,7 +5,7 @@#if defined(CONFIG_CC_IS_CLANG ) &&CONFIG_CLANG_VERSION <170000 #define __head __section(".head.text") __no_sanitize_undefined __no_stack_protector#else -#define __head __section(".head.text") __no_sanitize_undefined +#define __head __section(".head.text") __no_sanitize_undefined __no_sanitize_coverage#endif struct x86_mapping_info {
include/linux/init.h +3 -1
@@ -49,7 +49,9 @@/* These are for everybody (although not all archs will actually discard it in modules) */ -#define __init __section(".init.text") __cold __latent_entropy __noinitretpoline +#define __init __section(".init.text") __cold __latent_entropy \ + __noinitretpoline \ + __no_sanitize_coverage#define __initdata __section(".init.data")#define __initconst __section(".init.rodata")#define __exitdata __section(".exit.data")
Signature · 1 line
2.34.1
kernel test robot
build botRe: [PATCH v3 10/13] init.h: Disable sanitizer coverage for __init and __head
kernel test robot noticed the following build warnings:
Hi Kees,
kernel test robot noticed the following build warnings:
[auto build test WARNING on kees/for-next/hardening]
[also build test WARNING on tip/x86/core arm64/for-next/core s390/features linus/master v6.16-rc6] [If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Kees-Cook/stackleak-Rename-STACKLEAK-to-KSTACK_ERASE/20250718-072844 base: https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening patch link: https://lore.kernel.org/r/20250717232519.2984886-10-kees%40kernel.org patch subject: [PATCH v3 10/13] init.h: Disable sanitizer coverage for __init and __head config: arm64-randconfig-003-20250719 (https://download.01.org/0day-ci/archive/20250719/[email protected]/config) compiler: aarch64-linux-gcc (GCC) 15.1.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250719/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>, old ones prefixed by <<):
>> WARNING: modpost: vmlinux: section mismatch in reference: do_trace_initcall_finish.isra.0+0x3c (section: .text.unlikely) -> trace_initcall_finish_cb.constprop.0 (section: .init.text) >> WARNING: modpost: vmlinux: section mismatch in reference: do_trace_initcall_start.isra.0+0x3c (section: .text.unlikely) -> trace_initcall_start_cb.constprop.0 (section: .init.text)
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
kernel test robot
build botRe: [PATCH v3 10/13] init.h: Disable sanitizer coverage for __init and __head
In reply to Kees Cookkernel test robot noticed the following build errors:
Hi Kees,
kernel test robot noticed the following build errors:
[auto build test ERROR on kees/for-next/hardening]
[also build test ERROR on tip/x86/core arm64/for-next/core s390/features linus/master v6.16-rc6 next-20250718] [If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Kees-Cook/stackleak-Rename-STACKLEAK-to-KSTACK_ERASE/20250718-072844 base: https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening patch link: https://lore.kernel.org/r/20250717232519.2984886-10-kees%40kernel.org patch subject: [PATCH v3 10/13] init.h: Disable sanitizer coverage for __init and __head config: powerpc-randconfig-003-20250719 (https://download.01.org/0day-ci/archive/20250719/[email protected]/config) compiler: powerpc-linux-gcc (GCC) 12.5.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250719/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
powerpc-linux-ld: drivers/char/hw_random/nomadik-rng.o: in function `nmk_rng_remove':
nomadik-rng.c:(.text+0x60): undefined reference to `amba_release_regions'
powerpc-linux-ld: drivers/char/hw_random/nomadik-rng.o: in function `nmk_rng_probe':
nomadik-rng.c:(.text+0x128): undefined reference to `amba_request_regions'
>> powerpc-linux-ld: nomadik-rng.c:(.text+0x1a4): undefined reference to `amba_release_regions'
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Kees Cook
maintainerPATCH v3 11/13 kstack_erase: Support Clang stack depth tracking
In reply to Kees CookWire up CONFIG_KSTACK_ERASE to Clang 21's new stack depth tracking callback[1] option.
---
Cc: Arnd Bergmann <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nicolas Schier <[email protected]>
Cc: Marco Elver <[email protected]>
Cc: Andrey Konovalov <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
Cc: <[email protected]>
--- security/Kconfig.hardening | 5 ++++- scripts/Makefile.kstack_erase | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-)
security/Kconfig.hardening +4 -1
@@ -82,10 +82,13 @@ choice endchoice +config CC_HAS_SANCOV_STACK_DEPTH_CALLBACK + def_bool $(cc-option,-fsanitize-coverage-stack-depth-callback-min=1) + config KSTACK_ERASE bool "Poison kernel stack before returning from syscalls" depends on HAVE_ARCH_KSTACK_ERASE - depends on GCC_PLUGINS + depends on GCC_PLUGINS || CC_HAS_SANCOV_STACK_DEPTH_CALLBACK help This option makes the kernel erase the kernel stack before returning from system calls. This has the effect of leaving
scripts/Makefile.kstack_erase +6 -0
@@ -8,6 +8,12 @@ kstack-erase-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK_VERBOSE) += -fplugin-arg-stack DISABLE_KSTACK_ERASE := -fplugin-arg-stackleak_plugin-disable endif +ifdef CONFIG_CC_IS_CLANG +kstack-erase-cflags-y += -fsanitize-coverage=stack-depth +kstack-erase-cflags-y += -fsanitize-coverage-stack-depth-callback-min=$(CONFIG_KSTACK_ERASE_TRACK_MIN_SIZE) +DISABLE_KSTACK_ERASE := -fno-sanitize-coverage=stack-depth +endif + KSTACK_ERASE_CFLAGS := $(kstack-erase-cflags-y) export STACKLEAK_CFLAGS DISABLE_KSTACK_ERASE
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v3 12/13 configs/hardening: Enable CONFIG_KSTACK_ERASE
In reply to Kees CookSince we can wipe the stack with both Clang and GCC plugins, enable this for the "hardening.config" for wider testing.
---
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: <[email protected]>
--- kernel/configs/hardening.config | 3 +++ 1 file changed, 3 insertions(+)
kernel/configs/hardening.config +3 -0
@@ -63,6 +63,9 @@ CONFIG_INIT_ON_ALLOC_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
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v3 13/13 configs/hardening: Enable CONFIG_INIT_ON_FREE_DEFAULT_ON
In reply to Kees CookTo reduce stale data lifetimes, enable CONFIG_INIT_ON_FREE_DEFAULT_ON as well. This matches the addition of CONFIG_STACKLEAK=y, which is doing similar for stack memory.
---
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: <[email protected]>
--- kernel/configs/hardening.config | 3 +++ 1 file changed, 3 insertions(+)
kernel/configs/hardening.config +3 -0
@@ -60,6 +60,9 @@ 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
Signature · 1 line
2.34.1
This series was applied to riscv/linux.git (fixes) by Kees Cook <[email protected]>:
Hello:
This series was applied to riscv/linux.git (fixes) by Kees Cook <[email protected]>:
Quoted 9 lines · On Thu, 17 Jul 2025 16:25:05 -0700 you wrote:
v3:
- split up and drop__initvs inline patches that went via arch trees
- apply feedback about preferring__initto__always_inline
- incorporate Ritesh Harjani's patch for__initcleanups in powerpc
- wider build testing on older compilers
v2: https://lore.kernel.org/lkml/[email protected]/
v1: https://lore.kernel.org/lkml/[email protected]/[...]
Here is the summary with links:
- [v3,01/13] stackleak: Rename STACKLEAK to KSTACK_ERASE
(no matching commit)
- [v3,02/13] stackleak: Rename stackleak_track_stack to __sanitizer_cov_stack_depth (no matching commit)
- [v3,03/13] stackleak: Split KSTACK_ERASE_CFLAGS from GCC_PLUGINS_CFLAGS (no matching commit)
- [v3,04/13] x86: Handle KCOV __init vs inline mismatches
(no matching commit)
- [v3,05/13] arm: Handle KCOV __init vs inline mismatches
(no matching commit)
- [v3,06/13] arm64: Handle KCOV __init vs inline mismatches
https://git.kernel.org/riscv/c/65c430906eff - [v3,07/13] s390: Handle KCOV __init vs inline mismatches https://git.kernel.org/riscv/c/c64d6be1a6f8 - [v3,08/13] powerpc/mm/book3s64: Move kfence and debug_pagealloc related calls to __init section https://git.kernel.org/riscv/c/645d1b666498 - [v3,09/13] mips: Handle KCOV __init vs inline mismatch https://git.kernel.org/riscv/c/d01daf9d95c9 - [v3,10/13] init.h: Disable sanitizer coverage for __init and __head https://git.kernel.org/riscv/c/381a38ea53d2 - [v3,11/13] kstack_erase: Support Clang stack depth tracking (no matching commit) - [v3,12/13] configs/hardening: Enable CONFIG_KSTACK_ERASE https://git.kernel.org/riscv/c/4c56d9f7e75e - [v3,13/13] configs/hardening: Enable CONFIG_INIT_ON_FREE_DEFAULT_ON https://git.kernel.org/riscv/c/437641a72d0a
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html