stackleak: Support Clang stack depth tracking
Subsystems (23)
Kees Cook
maintainercover stackleak: Support Clang stack depth tracking
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
v1:
- Finalize Clang URLs for landed feature
- Perform CFLAGS enabling more sanely, as done for randstruct
- Split __no_sanitize_coverage into separate patch
- Update hardening.config and MAINTAINERS
- Fix bug found with nvme tree
RFC: https://lore.kernel.org/lkml/[email protected]/
Kees Cook (8):
nvme-pci: Make nvme_pci_npages_prp() __always_inline init.h: Disable sanitizer coverage for __init and __head
stackleak: Rename CONFIG_GCC_PLUGIN_STACKLEAK to CONFIG_STACKLEAK
stackleak: Rename stackleak_track_stack to __sanitizer_cov_stack_depth
stackleak: Split STACKLEAK_CFLAGS from GCC_PLUGINS_CFLAGS
stackleak: Support Clang stack depth tracking configs/hardening: Enable CONFIG_STACKLEAK configs/hardening: Enable CONFIG_INIT_ON_FREE_DEFAULT_ON
security/Kconfig.hardening | 25 ++++++---- 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 | 6 +-- kernel/Makefile | 4 +- lib/Makefile | 2 +- scripts/Makefile.gcc-plugins | 16 +------ scripts/Makefile.stackleak | 21 +++++++++ scripts/gcc-plugins/stackleak_plugin.c | 52 ++++++++++----------- Documentation/admin-guide/sysctl/kernel.rst | 2 +- Documentation/security/self-protection.rst | 2 +- arch/x86/entry/calling.h | 4 +- arch/x86/include/asm/init.h | 2 +- include/linux/init.h | 4 +- include/linux/sched.h | 4 +- include/linux/stackleak.h | 6 +-- 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 +- drivers/misc/lkdtm/stackleak.c | 8 ++-- drivers/nvme/host/pci.c | 2 +- kernel/stackleak.c | 4 +- tools/objtool/check.c | 2 +- tools/testing/selftests/lkdtm/config | 2 +- MAINTAINERS | 6 ++- kernel/configs/hardening.config | 6 +++ 36 files changed, 122 insertions(+), 90 deletions(-) create mode 100644 scripts/Makefile.stackleak
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH 1/8 nvme-pci: Make nvme_pci_npages_prp() __always_inline
The only reason nvme_pci_npages_prp() could be used as a compile-time known result in BUILD_BUG_ON() is because the compiler was always choosing to inline the function. Under special circumstances (sanitizer coverage functions disabled for __init functions on ARCH=um), the compiler decided to stop inlining it:
drivers/nvme/host/pci.c: In function 'nvme_init':
include/linux/compiler_types.h:557:45: error: call to '__compiletime_assert_678' declared with attribute error: BUILD_BUG_ON failed: nvme_pci_npages_prp() > NVME_MAX_NR_ALLOCATIONS
557 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^
include/linux/compiler_types.h:538:25: note: in definition of macro '__compiletime_assert'
538 | prefix ## suffix(); \
| ^~~~~~
include/linux/compiler_types.h:557:9: note: in expansion of macro '_compiletime_assert'
557 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:50:9: note: in expansion of macro 'BUILD_BUG_ON_MSG'
50 | BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
| ^~~~~~~~~~~~~~~~
drivers/nvme/host/pci.c:3804:9: note: in expansion of macro 'BUILD_BUG_ON'
3804 | BUILD_BUG_ON(nvme_pci_npages_prp() > NVME_MAX_NR_ALLOCATIONS);
| ^~~~~~~~~~~~Force it to be __always_inline to make sure it is always available for use with BUILD_BUG_ON().
---
Cc: Keith Busch <[email protected]>
Cc: Jens Axboe <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: <[email protected]>
--- drivers/nvme/host/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nvme/host/pci.c +1 -1
@@ -390,7 +390,7 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, __le32 *dbbuf_db,* as it only leads to a small amount of wasted memory for the lifetime of * the I/O. */ -static int nvme_pci_npages_prp (void ) +static __always_inline int nvme_pci_npages_prp(void) {unsigned max_bytes = (NVME_MAX_KB_SZ *1024 ) +NVME_CTRL_PAGE_SIZE ;unsigned nprps =DIV_ROUND_UP (max_bytes,NVME_CTRL_PAGE_SIZE );
Signature · 1 line
2.34.1
Re: [PATCH 1/8] nvme-pci: Make nvme_pci_npages_prp() __always_inline
Quoted 2 lines · Kees Cook
Force it to be
__always_inlineto make sure it is always available for use withBUILD_BUG_ON().
Kees Cook
maintainerPATCH 2/8 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_STACKLEAK. 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 appears safe 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
Re: [PATCH 2/8] init.h: Disable sanitizer coverage for __init and __head
+Cc KCOV maintainers
Quoted 10 lines · Kees Cook
While
__noinstralready contained__no_sanitize_coverage, it needs to be added to__initand__headsection markings to support the Clang implementation ofCONFIG_STACKLEAK. 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
__headnor__initeither ("We are interested in code coverage as a function of a syscall inputs"[1]), so this appears safe to disable for them as well.
@ Dmitry, Aleksandr - Will this produce some unwanted side-effects for syzbot? I also think it's safe, but just double checking.
Quoted 2 lines
Quoted 57 lines
---
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
-2@@ -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") --2.34.1
Re: [PATCH 2/8] init.h: Disable sanitizer coverage for __init and __head
Quoted 10 lines · Marco Elver
+Cc KCOV maintainers
Quoted 6 lines · Kees Cook
While
__noinstralready contained__no_sanitize_coverage, it needs to be added to__initand__headsection markings to support the Clang implementation ofCONFIG_STACKLEAK. This is to make sure the stack depth tracking callback is not executed in unsupported contexts.
Quoted 7 lines
Quoted 4 lines
The other sanitizer coverage options (trace-pc and trace-cmp) aren't needed in
__headnor__initeither ("We are interested in code coverage as a function of a syscall inputs"[1]), so this appears safe to disable for them as well.@ Dmitry, Aleksandr - Will this produce some unwanted side-effects for syzbot? I also think it's safe, but just double checking.
I do not see any problems with this.
Quoted 62 lines
Quoted 2 lines
Acked-by Marco Elver <[email protected]>Quoted 57 lines
---
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
-2@@ -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") --2.34.1
kernel test robot
build botRe: [PATCH 2/8] init.h: Disable sanitizer coverage for __init and __head
In reply to Kees Cookkernel 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 arm64/for-next/core masahiroy-kbuild/for-next masahiroy-kbuild/fixes linus/master v6.15-rc6 next-20250513] [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/nvme-pci-Make-nvme_pci_npages_prp-__always_inline/20250508-021852 base: https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening patch link: https://lore.kernel.org/r/20250507181615.1947159-2-kees%40kernel.org patch subject: [PATCH 2/8] init.h: Disable sanitizer coverage for __init and __head config: x86_64-buildonly-randconfig-001-20250513 (https://download.01.org/0day-ci/archive/20250514/[email protected]/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250514/[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 >>):
drivers/mtd/maps/ichxrom.c: In function 'ichxrom_init_one.constprop':
>> drivers/mtd/maps/ichxrom.c:115:12: warning: 'byte' is used uninitialized [-Wuninitialized]
115 | if (byte == 0xff) {
| ^
drivers/mtd/maps/ichxrom.c:97:12: note: 'byte' was declared here
97 | u8 byte;
| ^~~~
--
drivers/mtd/maps/amd76xrom.c: In function 'amd76xrom_init_one.constprop':
>> drivers/mtd/maps/amd76xrom.c:108:12: warning: 'byte' is used uninitialized [-Wuninitialized]
108 | u8 byte;
| ^~~~vim +/byte +115 drivers/mtd/maps/ichxrom.c
^1da177e4c3f41 Linus Torvalds 2005-04-16 88
^1da177e4c3f41 Linus Torvalds 2005-04-16 89
e4106a7c8236eb Julia Lawall 2016-04-19 90 static int __init ichxrom_init_one(struct pci_dev *pdev,
^1da177e4c3f41 Linus Torvalds 2005-04-16 91 const struct pci_device_id *ent)
^1da177e4c3f41 Linus Torvalds 2005-04-16 92 {
^1da177e4c3f41 Linus Torvalds 2005-04-16 93 static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
^1da177e4c3f41 Linus Torvalds 2005-04-16 94 struct ichxrom_window *window = &ichxrom_window;
^1da177e4c3f41 Linus Torvalds 2005-04-16 95 struct ichxrom_map_info *map = NULL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 96 unsigned long map_top;
^1da177e4c3f41 Linus Torvalds 2005-04-16 97 u8 byte;
^1da177e4c3f41 Linus Torvalds 2005-04-16 98 u16 word;
^1da177e4c3f41 Linus Torvalds 2005-04-16 99
^1da177e4c3f41 Linus Torvalds 2005-04-16 100 /* For now I just handle the ichx and I assume there
^1da177e4c3f41 Linus Torvalds 2005-04-16 101 * are not a lot of resources up at the top of the address
^1da177e4c3f41 Linus Torvalds 2005-04-16 102 * space. It is possible to handle other devices in the
^1da177e4c3f41 Linus Torvalds 2005-04-16 103 * top 16MB but it is very painful. Also since
^1da177e4c3f41 Linus Torvalds 2005-04-16 104 * you can only really attach a FWH to an ICHX there
^1da177e4c3f41 Linus Torvalds 2005-04-16 105 * a number of simplifications you can make.
^1da177e4c3f41 Linus Torvalds 2005-04-16 106 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 107 * Also you can page firmware hubs if an 8MB window isn't enough
^1da177e4c3f41 Linus Torvalds 2005-04-16 108 * but don't currently handle that case either.
^1da177e4c3f41 Linus Torvalds 2005-04-16 109 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 110 window->pdev = pdev;
^1da177e4c3f41 Linus Torvalds 2005-04-16 111
^1da177e4c3f41 Linus Torvalds 2005-04-16 112 /* Find a region continuous to the end of the ROM window */
^1da177e4c3f41 Linus Torvalds 2005-04-16 113 window->phys = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 114 pci_read_config_byte(pdev, FWH_DEC_EN1, &byte);
^1da177e4c3f41 Linus Torvalds 2005-04-16 @115 if (byte == 0xff) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 116 window->phys = 0xffc00000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 117 pci_read_config_byte(pdev, FWH_DEC_EN2, &byte);
^1da177e4c3f41 Linus Torvalds 2005-04-16 118 if ((byte & 0x0f) == 0x0f) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 119 window->phys = 0xff400000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 120 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 121 else if ((byte & 0x0e) == 0x0e) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 122 window->phys = 0xff500000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 123 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 124 else if ((byte & 0x0c) == 0x0c) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 125 window->phys = 0xff600000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 126 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 127 else if ((byte & 0x08) == 0x08) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 128 window->phys = 0xff700000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 129 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 130 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 131 else if ((byte & 0xfe) == 0xfe) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 132 window->phys = 0xffc80000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 133 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 134 else if ((byte & 0xfc) == 0xfc) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 135 window->phys = 0xffd00000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 136 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 137 else if ((byte & 0xf8) == 0xf8) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 138 window->phys = 0xffd80000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 139 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 140 else if ((byte & 0xf0) == 0xf0) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 141 window->phys = 0xffe00000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 142 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 143 else if ((byte & 0xe0) == 0xe0) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 144 window->phys = 0xffe80000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 145 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 146 else if ((byte & 0xc0) == 0xc0) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 147 window->phys = 0xfff00000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 148 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 149 else if ((byte & 0x80) == 0x80) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 150 window->phys = 0xfff80000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 151 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 152
^1da177e4c3f41 Linus Torvalds 2005-04-16 153 if (window->phys == 0) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 154 printk(KERN_ERR MOD_NAME ": Rom window is closed\n");
^1da177e4c3f41 Linus Torvalds 2005-04-16 155 goto out;
^1da177e4c3f41 Linus Torvalds 2005-04-16 156 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 157 window->phys -= 0x400000UL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 158 window->size = (0xffffffffUL - window->phys) + 1UL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 159
^1da177e4c3f41 Linus Torvalds 2005-04-16 160 /* Enable writes through the rom window */
^1da177e4c3f41 Linus Torvalds 2005-04-16 161 pci_read_config_word(pdev, BIOS_CNTL, &word);
^1da177e4c3f41 Linus Torvalds 2005-04-16 162 if (!(word & 1) && (word & (1<<1))) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 163 /* The BIOS will generate an error if I enable
^1da177e4c3f41 Linus Torvalds 2005-04-16 164 * this device, so don't even try.
^1da177e4c3f41 Linus Torvalds 2005-04-16 165 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 166 printk(KERN_ERR MOD_NAME ": firmware access control, I can't enable writes\n");
^1da177e4c3f41 Linus Torvalds 2005-04-16 167 goto out;
^1da177e4c3f41 Linus Torvalds 2005-04-16 168 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 169 pci_write_config_word(pdev, BIOS_CNTL, word | 1);
^1da177e4c3f41 Linus Torvalds 2005-04-16 170
^1da177e4c3f41 Linus Torvalds 2005-04-16 171 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 172 * Try to reserve the window mem region. If this fails then
01d0afddf37cbb Geert Uytterhoeven 2015-05-21 173 * it is likely due to the window being "reserved" by the BIOS.
^1da177e4c3f41 Linus Torvalds 2005-04-16 174 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 175 window->rsrc.name = MOD_NAME;
^1da177e4c3f41 Linus Torvalds 2005-04-16 176 window->rsrc.start = window->phys;
^1da177e4c3f41 Linus Torvalds 2005-04-16 177 window->rsrc.end = window->phys + window->size - 1;
^1da177e4c3f41 Linus Torvalds 2005-04-16 178 window->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
^1da177e4c3f41 Linus Torvalds 2005-04-16 179 if (request_resource(&iomem_resource, &window->rsrc)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 180 window->rsrc.parent = NULL;
f9a5279c70af10 Joe Perches 2010-11-12 181 printk(KERN_DEBUG MOD_NAME ": "
f9a5279c70af10 Joe Perches 2010-11-12 182 "%s(): Unable to register resource %pR - kernel bug?\n",
f9a5279c70af10 Joe Perches 2010-11-12 183 __func__, &window->rsrc);
^1da177e4c3f41 Linus Torvalds 2005-04-16 184 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 185
^1da177e4c3f41 Linus Torvalds 2005-04-16 186 /* Map the firmware hub into my address space. */
4bdc0d676a6431 Christoph Hellwig 2020-01-06 187 window->virt = ioremap(window->phys, window->size);
^1da177e4c3f41 Linus Torvalds 2005-04-16 188 if (!window->virt) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 189 printk(KERN_ERR MOD_NAME ": ioremap(%08lx, %08lx) failed\n",
^1da177e4c3f41 Linus Torvalds 2005-04-16 190 window->phys, window->size);
^1da177e4c3f41 Linus Torvalds 2005-04-16 191 goto out;
^1da177e4c3f41 Linus Torvalds 2005-04-16 192 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 193
^1da177e4c3f41 Linus Torvalds 2005-04-16 194 /* Get the first address to look for an rom chip at */
^1da177e4c3f41 Linus Torvalds 2005-04-16 195 map_top = window->phys;
^1da177e4c3f41 Linus Torvalds 2005-04-16 196 if ((window->phys & 0x3fffff) != 0) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 197 map_top = window->phys + 0x400000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 198 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 199 #if 1
^1da177e4c3f41 Linus Torvalds 2005-04-16 200 /* The probe sequence run over the firmware hub lock
^1da177e4c3f41 Linus Torvalds 2005-04-16 201 * registers sets them to 0x7 (no access).
^1da177e4c3f41 Linus Torvalds 2005-04-16 202 * Probe at most the last 4M of the address space.
^1da177e4c3f41 Linus Torvalds 2005-04-16 203 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 204 if (map_top < 0xffc00000) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 205 map_top = 0xffc00000;
^1da177e4c3f41 Linus Torvalds 2005-04-16 206 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 207 #endif
^1da177e4c3f41 Linus Torvalds 2005-04-16 208 /* Loop through and look for rom chips */
^1da177e4c3f41 Linus Torvalds 2005-04-16 209 while((map_top - 1) < 0xffffffffUL) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 210 struct cfi_private *cfi;
^1da177e4c3f41 Linus Torvalds 2005-04-16 211 unsigned long offset;
^1da177e4c3f41 Linus Torvalds 2005-04-16 212 int i;
^1da177e4c3f41 Linus Torvalds 2005-04-16 213
^1da177e4c3f41 Linus Torvalds 2005-04-16 214 if (!map) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 215 map = kmalloc(sizeof(*map), GFP_KERNEL);
4883307c6d8e59 Zhen Lei 2021-06-10 216 if (!map)
^1da177e4c3f41 Linus Torvalds 2005-04-16 217 goto out;
^1da177e4c3f41 Linus Torvalds 2005-04-16 218 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 219 memset(map, 0, sizeof(*map));
^1da177e4c3f41 Linus Torvalds 2005-04-16 220 INIT_LIST_HEAD(&map->list);
^1da177e4c3f41 Linus Torvalds 2005-04-16 221 map->map.name = map->map_name;
^1da177e4c3f41 Linus Torvalds 2005-04-16 222 map->map.phys = map_top;
^1da177e4c3f41 Linus Torvalds 2005-04-16 223 offset = map_top - window->phys;
^1da177e4c3f41 Linus Torvalds 2005-04-16 224 map->map.virt = (void __iomem *)
^1da177e4c3f41 Linus Torvalds 2005-04-16 225 (((unsigned long)(window->virt)) + offset);
^1da177e4c3f41 Linus Torvalds 2005-04-16 226 map->map.size = 0xffffffffUL - map_top + 1UL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 227 /* Set the name of the map to the address I am trying */
3a38d3af92c423 Andrew Morton 2007-02-17 228 sprintf(map->map_name, "%s @%08Lx",
3a38d3af92c423 Andrew Morton 2007-02-17 229 MOD_NAME, (unsigned long long)map->map.phys);
^1da177e4c3f41 Linus Torvalds 2005-04-16 230
^1da177e4c3f41 Linus Torvalds 2005-04-16 231 /* Firmware hubs only use vpp when being programmed
^1da177e4c3f41 Linus Torvalds 2005-04-16 232 * in a factory setting. So in-place programming
^1da177e4c3f41 Linus Torvalds 2005-04-16 233 * needs to use a different method.
^1da177e4c3f41 Linus Torvalds 2005-04-16 234 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 235 for(map->map.bankwidth = 32; map->map.bankwidth;
^1da177e4c3f41 Linus Torvalds 2005-04-16 236 map->map.bankwidth >>= 1)
^1da177e4c3f41 Linus Torvalds 2005-04-16 237 {
^1da177e4c3f41 Linus Torvalds 2005-04-16 238 char **probe_type;
^1da177e4c3f41 Linus Torvalds 2005-04-16 239 /* Skip bankwidths that are not supported */
^1da177e4c3f41 Linus Torvalds 2005-04-16 240 if (!map_bankwidth_supported(map->map.bankwidth))
^1da177e4c3f41 Linus Torvalds 2005-04-16 241 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 242
^1da177e4c3f41 Linus Torvalds 2005-04-16 243 /* Setup the map methods */
^1da177e4c3f41 Linus Torvalds 2005-04-16 244 simple_map_init(&map->map);
^1da177e4c3f41 Linus Torvalds 2005-04-16 245
^1da177e4c3f41 Linus Torvalds 2005-04-16 246 /* Try all of the probe methods */
^1da177e4c3f41 Linus Torvalds 2005-04-16 247 probe_type = rom_probe_types;
^1da177e4c3f41 Linus Torvalds 2005-04-16 248 for(; *probe_type; probe_type++) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 249 map->mtd = do_map_probe(*probe_type, &map->map);
^1da177e4c3f41 Linus Torvalds 2005-04-16 250 if (map->mtd)
^1da177e4c3f41 Linus Torvalds 2005-04-16 251 goto found;
^1da177e4c3f41 Linus Torvalds 2005-04-16 252 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 253 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 254 map_top += ROM_PROBE_STEP_SIZE;
^1da177e4c3f41 Linus Torvalds 2005-04-16 255 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 256 found:
^1da177e4c3f41 Linus Torvalds 2005-04-16 257 /* Trim the size if we are larger than the map */
^1da177e4c3f41 Linus Torvalds 2005-04-16 258 if (map->mtd->size > map->map.size) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 259 printk(KERN_WARNING MOD_NAME
69423d99fc182a Adrian Hunter 2008-12-10 260 " rom(%llu) larger than window(%lu). fixing...\n",
69423d99fc182a Adrian Hunter 2008-12-10 261 (unsigned long long)map->mtd->size, map->map.size);
^1da177e4c3f41 Linus Torvalds 2005-04-16 262 map->mtd->size = map->map.size;
^1da177e4c3f41 Linus Torvalds 2005-04-16 263 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 264 if (window->rsrc.parent) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 265 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 266 * Registering the MTD device in iomem may not be possible
^1da177e4c3f41 Linus Torvalds 2005-04-16 267 * if there is a BIOS "reserved" and BUSY range. If this
^1da177e4c3f41 Linus Torvalds 2005-04-16 268 * fails then continue anyway.
^1da177e4c3f41 Linus Torvalds 2005-04-16 269 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 270 map->rsrc.name = map->map_name;
^1da177e4c3f41 Linus Torvalds 2005-04-16 271 map->rsrc.start = map->map.phys;
^1da177e4c3f41 Linus Torvalds 2005-04-16 272 map->rsrc.end = map->map.phys + map->mtd->size - 1;
^1da177e4c3f41 Linus Torvalds 2005-04-16 273 map->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
^1da177e4c3f41 Linus Torvalds 2005-04-16 274 if (request_resource(&window->rsrc, &map->rsrc)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 275 printk(KERN_ERR MOD_NAME
^1da177e4c3f41 Linus Torvalds 2005-04-16 276 ": cannot reserve MTD resource\n");
^1da177e4c3f41 Linus Torvalds 2005-04-16 277 map->rsrc.parent = NULL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 278 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 279 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 280
^1da177e4c3f41 Linus Torvalds 2005-04-16 281 /* Make the whole region visible in the map */
^1da177e4c3f41 Linus Torvalds 2005-04-16 282 map->map.virt = window->virt;
^1da177e4c3f41 Linus Torvalds 2005-04-16 283 map->map.phys = window->phys;
^1da177e4c3f41 Linus Torvalds 2005-04-16 284 cfi = map->map.fldrv_priv;
^1da177e4c3f41 Linus Torvalds 2005-04-16 285 for(i = 0; i < cfi->numchips; i++) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 286 cfi->chips[i].start += offset;
^1da177e4c3f41 Linus Torvalds 2005-04-16 287 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 288
^1da177e4c3f41 Linus Torvalds 2005-04-16 289 /* Now that the mtd devices is complete claim and export it */
^1da177e4c3f41 Linus Torvalds 2005-04-16 290 map->mtd->owner = THIS_MODULE;
ee0e87b174bb41 Jamie Iles 2011-05-23 291 if (mtd_device_register(map->mtd, NULL, 0)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 292 map_destroy(map->mtd);
^1da177e4c3f41 Linus Torvalds 2005-04-16 293 map->mtd = NULL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 294 goto out;
^1da177e4c3f41 Linus Torvalds 2005-04-16 295 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 296
^1da177e4c3f41 Linus Torvalds 2005-04-16 297
^1da177e4c3f41 Linus Torvalds 2005-04-16 298 /* Calculate the new value of map_top */
^1da177e4c3f41 Linus Torvalds 2005-04-16 299 map_top += map->mtd->size;
^1da177e4c3f41 Linus Torvalds 2005-04-16 300
^1da177e4c3f41 Linus Torvalds 2005-04-16 301 /* File away the map structure */
^1da177e4c3f41 Linus Torvalds 2005-04-16 302 list_add(&map->list, &window->maps);
^1da177e4c3f41 Linus Torvalds 2005-04-16 303 map = NULL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 304 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 305
^1da177e4c3f41 Linus Torvalds 2005-04-16 306 out:
^1da177e4c3f41 Linus Torvalds 2005-04-16 307 /* Free any left over map structures */
^1da177e4c3f41 Linus Torvalds 2005-04-16 308 kfree(map);
fa671646f61182 Jesper Juhl 2005-11-07 309
^1da177e4c3f41 Linus Torvalds 2005-04-16 310 /* See if I have any map structures */
^1da177e4c3f41 Linus Torvalds 2005-04-16 311 if (list_empty(&window->maps)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 312 ichxrom_cleanup(window);
^1da177e4c3f41 Linus Torvalds 2005-04-16 313 return -ENODEV;
^1da177e4c3f41 Linus Torvalds 2005-04-16 314 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 315 return 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 316 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 317 Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Kees Cook
maintainerPATCH 3/8 stackleak: Rename CONFIG_GCC_PLUGIN_STACKLEAK to CONFIG_STACKLEAK
In reply to Kees CookIn preparation for adding Clang sanitizer coverage stack depth tracking that can support stack depth callbacks, remove "GCC_PLUGIN" from "CONFIG_GCC_PLUGIN_STACKLEAK" and remove "PLUGIN" from "DISABLE_STACKLEAK_PLUGIN". Rearrange the Kconfig to have a top-level CONFIG_STACKLEAK that will depend on either GCC plugins or Clang soon.
While here, also split "prev_lowest_stack" into CONFIG_STACKLEAK_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]>
--- security/Kconfig.hardening | 18 +++++++++++------- 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 | 6 +++--- kernel/Makefile | 4 ++-- lib/Makefile | 2 +- scripts/Makefile.gcc-plugins | 4 ++-- Documentation/admin-guide/sysctl/kernel.rst | 2 +- Documentation/security/self-protection.rst | 2 +- arch/x86/entry/calling.h | 4 ++-- include/linux/sched.h | 4 +++- include/linux/stackleak.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 +- drivers/misc/lkdtm/stackleak.c | 8 ++++---- tools/testing/selftests/lkdtm/config | 2 +- 22 files changed, 43 insertions(+), 37 deletions(-)
security/Kconfig.hardening +11 -7
@@ -158,10 +158,10 @@ config GCC_PLUGIN_STRUCTLEAK_VERBOSE initialized. Since not all existing initializers are detected by the plugin, this can produce false positive warnings. -config GCC_PLUGIN_STACKLEAK +config STACKLEAK bool "Poison kernel stack before returning from syscalls" - depends on GCC_PLUGINS depends on HAVE_ARCH_STACKLEAK + depends on GCC_PLUGINS help This option makes the kernel erase the kernel stack before returning from system calls. This has the effect of leaving
@@ -179,6 +179,10 @@ config GCC_PLUGIN_STACKLEAK are advised to test this feature on your expected workload before deploying it. +config GCC_PLUGIN_STACKLEAK + def_bool STACKLEAK + depends on GCC_PLUGINS + help This plugin was ported from grsecurity/PaX. More information at: * https://grsecurity.net/ * https://pax.grsecurity.net/
@@ -197,9 +201,9 @@ config STACKLEAK_TRACK_MIN_SIZE int "Minimum stack frame size of functions tracked by STACKLEAK" default 100 range 0 4096 - depends on GCC_PLUGIN_STACKLEAK + depends on STACKLEAK help - The STACKLEAK gcc plugin instruments the kernel code for tracking + The STACKLEAK options 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.
@@ -207,7 +211,7 @@ config STACKLEAK_TRACK_MIN_SIZE config STACKLEAK_METRICS bool "Show STACKLEAK metrics in the /proc file system" - depends on GCC_PLUGIN_STACKLEAK + depends on STACKLEAK depends on PROC_FS help If this is set, STACKLEAK metrics for every task are available in
@@ -219,11 +223,11 @@ config STACKLEAK_METRICS config STACKLEAK_RUNTIME_DISABLE bool "Allow runtime disabling of kernel stack erasing" - depends on GCC_PLUGIN_STACKLEAK + depends on STACKLEAK 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_STACKLEAK. 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_STACKLEAK) 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_STACKLEAK) \ $(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_STACKLEAK) 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_STACKLEAK) \ $(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_STACKLEAK) -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_STACKLEAK) -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 +3 -3
@@ -22,15 +22,15 @@ 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_STACKLEAK) \ -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_STACKLEAK) cflags-$(CONFIG_RISCV) += -fpic -DNO_ALTERNATIVE -mno-relax \ - $(DISABLE_STACKLEAK_PLUGIN) + $(DISABLE_STACKLEAK) cflags-$(CONFIG_LOONGARCH) += -fpie cflags-$(CONFIG_EFI_PARAMS_FROM_FDT) += -I$(srctree)/scripts/dtc/libfdt
kernel/Makefile +2 -2
@@ -137,8 +137,8 @@ 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 +CFLAGS_stackleak.o += $(DISABLE_STACKLEAK) +obj-$(CONFIG_STACKLEAK) += stackleak.o KASAN_SANITIZE_stackleak.o := n KCSAN_SANITIZE_stackleak.o := n KCOV_INSTRUMENT_stackleak.o := n
lib/Makefile +1 -1
@@ -337,7 +337,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_STACKLEAK) obj-$(CONFIG_SBITMAP) += sbitmap.o
scripts/Makefile.gcc-plugins +2 -2
@@ -32,9 +32,9 @@ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ 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_STACKLEAK += -fplugin-arg-stackleak_plugin-disable endif -export DISABLE_STACKLEAK_PLUGIN +export DISABLE_STACKLEAK # 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 +1 -1
@@ -1465,7 +1465,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_STACKLEAK``. That erasing reduces the information which kernel stack leak bugs can reveal and blocks some uninitialized stack variable attacks.
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_STACKLEAK``), wipe heap memory on a free. This frustrates many uninitialized variable attacks, stack content exposures, heap content exposures, and use-after-free attacks.
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_STACKLEAK 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_STACKLEAK call stackleak_erase #endif .endm
include/linux/sched.h +3 -1
@@ -1599,8 +1599,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_STACKLEAK unsigned long lowest_stack; +#endif +#ifdef CONFIG_STACKLEAK_METRICS unsigned long prev_lowest_stack;#endif
include/linux/stackleak.h +2 -2
@@ -12,7 +12,7 @@#define STACKLEAK_POISON -0xBEEF#define STACKLEAK_SEARCH_DEPTH 128 -#ifdef CONFIG_GCC_PLUGIN_STACKLEAK +#ifdef CONFIG_STACKLEAK #include <asm/stacktrace.h> #include <linux/linkage.h>
@@ -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_STACKLEAK */ static inline void stackleak_task_init (struct task_struct *t) { }#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_STACKLEAK 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_STACKLEAK 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_STACKLEAK 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_STACKLEAK brasl %r14,stackleak_erase_on_task_stack #endif .endm
drivers/misc/lkdtm/stackleak.c +4 -4
@@ -11,7 +11,7 @@#include "lkdtm.h" #include <linux/stackleak.h> -#if defined(CONFIG_GCC_PLUGIN_STACKLEAK ) +#if defined(CONFIG_STACKLEAK )/* * Check that stackleak tracks the lowest stack pointer and erases the stack * below this as expected.
@@ -129,16 +129,16 @@ static void lkdtm_STACKLEAK_ERASING(void)check_stackleak_irqoff ();local_irq_restore (flags); } -#else /* defined(CONFIG_GCC_PLUGIN_STACKLEAK) */ +#else /* defined(CONFIG_STACKLEAK) */ static void lkdtm_STACKLEAK_ERASING (void ) {if (IS_ENABLED (CONFIG_HAVE_ARCH_STACKLEAK )) { -pr_err ("XFAIL: stackleak is not enabled (CONFIG_GCC_PLUGIN_STACKLEAK=n)\n" ); +pr_err ("XFAIL: stackleak is not enabled (CONFIG_STACKLEAK=n)\n" ); }else {pr_err ("XFAIL: stackleak is not supported on this arch (HAVE_ARCH_STACKLEAK=n)\n" ); } } -#endif /* defined(CONFIG_GCC_PLUGIN_STACKLEAK) */ +#endif /* defined(CONFIG_STACKLEAK) */ static struct crashtype crashtypes[] = {CRASHTYPE (STACKLEAK_ERASING ),
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_STACKLEAK=y CONFIG_HARDENED_USERCOPY=y CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y CONFIG_INIT_ON_FREE_DEFAULT_ON=y
Signature · 1 line
2.34.1
Re: [PATCH 3/8] stackleak: Rename CONFIG_GCC_PLUGIN_STACKLEAK to CONFIG_STACKLEAK
security/Kconfig.hardening config STACKLEAK_TRACK_MIN_SIZE · line 206
Quoted 2 lines · Kees Cook
security/Kconfig.hardening +1
-1- The STACKLEAK gcc plugin instruments the kernel code for tracking + The STACKLEAK options instruments the kernel code for tracking
speling.
Also, any chance to fix this terrible name? Should be something like KSTACKZERO or KSTACKCLEAR, to tell people that it doesn't leak the stack but prevents leaks on the stack by clearing it, and that it's about the kernel stack, not any other stack.
Thanks,
Ingo
Kees Cook
maintainerRe: [PATCH 3/8] stackleak: Rename CONFIG_GCC_PLUGIN_STACKLEAK to CONFIG_STACKLEAK
Quoted 7 lines · Ingo Molnar
security/Kconfig.hardening config STACKLEAK_TRACK_MIN_SIZE · line 206
Quoted 2 lines · Kees Cook
security/Kconfig.hardening +1
-1- The STACKLEAK gcc plugin instruments the kernel code for tracking + The STACKLEAK options instruments the kernel code for trackingspeling.
Thanks!
Quoted 4 lines
Also, any chance to fix this terrible name? Should be something like KSTACKZERO or KSTACKCLEAR, to tell people that it doesn't leak the stack but prevents leaks on the stack by clearing it, and that it's about the kernel stack, not any other stack.
Yeah, better to name it for what it does rather than want to protects against. The internal naming for what it does is "stack erase", so perhaps KSTACK_ERASE ?
-Kees
Signature · 1 line
Kees Cook
Re: [PATCH 3/8] stackleak: Rename CONFIG_GCC_PLUGIN_STACKLEAK to CONFIG_STACKLEAK
Quoted 11 lines · Kees Cook
Quoted 7 lines · Ingo Molnar
security/Kconfig.hardening config STACKLEAK_TRACK_MIN_SIZE · line 206
Quoted 2 lines · Kees Cook
security/Kconfig.hardening +1
-1- The STACKLEAK gcc plugin instruments the kernel code for tracking + The STACKLEAK options instruments the kernel code for trackingspeling.
Thanks!
Quoted 8 lines
Quoted 4 lines
Also, any chance to fix this terrible name? Should be something like KSTACKZERO or KSTACKCLEAR, to tell people that it doesn't leak the stack but prevents leaks on the stack by clearing it, and that it's about the kernel stack, not any other stack.
Yeah, better to name it for what it does rather than want to protects against. The internal naming for what it does is "stack erase", so perhaps
KSTACK_ERASE?
That's even better, and I like the word separation as well. Thanks!
Ingo
Kees Cook
maintainerPATCH 4/8 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 it has no external dependencies.
---
Cc: Arnd Bergmann <[email protected]>
Cc: <[email protected]>
--- security/Kconfig.hardening | 4 +- scripts/gcc-plugins/stackleak_plugin.c | 52 +++++++++++++------------- include/linux/stackleak.h | 2 +- kernel/stackleak.c | 4 +- tools/objtool/check.c | 2 +- 5 files changed, 32 insertions(+), 32 deletions(-)
security/Kconfig.hardening +2 -2
@@ -205,8 +205,8 @@ config STACKLEAK_TRACK_MIN_SIZE help The STACKLEAK options 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 STACKLEAK_METRICS
scripts/gcc-plugins/stackleak_plugin.c +26 -26
159 lines not on this page · raw message
include/linux/stackleak.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_STACKLEAK */ static inline void stackleak_task_init (struct task_struct *t) { }
kernel/stackleak.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
@@ -1191,7 +1191,7 @@ static const char *uaccess_safe_builtin[] = {"__ubsan_handle_shift_out_of_bounds" ,"__ubsan_handle_load_invalid_value" ,/* STACKLEAK */ -"stackleak_track_stack" , +"__sanitizer_cov_stack_depth" ,/* TRACE_BRANCH_PROFILING */ "ftrace_likely_update",/* STACKPROTECTOR */
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH 5/8 stackleak: Split STACKLEAK_CFLAGS from GCC_PLUGINS_CFLAGS
In reply to Kees CookIn preparation for Clang stack depth tracking for stackleak, split the stackleak-specific cflags out of GCC_PLUGINS_CFLAGS into STACKLEAK_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.stackleak | 15 +++++++++++++++ MAINTAINERS | 6 ++++-- 8 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 scripts/Makefile.stackleak
Makefile +1 -0
@@ -1089,6 +1089,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_STACKLEAK) += scripts/Makefile.stackleak 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) $(STACKLEAK_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) $(STACKLEAK_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) $(STACKLEAK_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 $(STACKLEAK_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) $(STACKLEAK_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 $(STACKLEAK_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
@@ -22,20 +22,6 @@ export DISABLE_STRUCTLEAK_PLUGIN gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) \ += -DSTRUCTLEAK_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_STACKLEAK_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 += -fplugin-arg-stackleak_plugin-disable -endif -export DISABLE_STACKLEAK - # 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
@@ -50,6 +36,8 @@ gcc-plugin-external-$(CONFIG_GCC_PLUGIN_SANCOV) \ += sancov_plugin.so 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.stackleak new file +15 -0
@@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 + +ifdef CONFIG_GCC_PLUGIN_STACKLEAK +stackleak-cflags-y += -fplugin=$(objtree)/scripts/gcc-plugins/stackleak_plugin.so +stackleak-cflags-y += -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_STACKLEAK_TRACK_MIN_SIZE) +stackleak-cflags-y += -fplugin-arg-stackleak_plugin-arch=$(SRCARCH) +stackleak-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK_VERBOSE) += -fplugin-arg-stackleak_plugin-verbose +DISABLE_STACKLEAK := -fplugin-arg-stackleak_plugin-disable +endif + +STACKLEAK_CFLAGS := $(stackleak-cflags-y) + +export STACKLEAK_CFLAGS DISABLE_STACKLEAK + +KBUILD_CFLAGS += $(STACKLEAK_CFLAGS)
MAINTAINERS +4 -2
@@ -9827,8 +9827,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/
@@ -12890,11 +12888,15 @@ F: Documentation/ABI/testing/sysfs-kernel-warn_count F: arch/*/configs/hardening.config F: include/linux/overflow.h F: include/linux/randomize_kstack.h +F: include/linux/stackleak.h F: include/linux/ucopysize.h F: kernel/configs/hardening.config +F: kernel/stackleak.c F: lib/tests/randstruct_kunit.c F: lib/tests/usercopy_kunit.c F: mm/usercopy.c +F: scripts/Makefile.randstruct +F: scripts/Makefile.stackleak 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 6/8 stackleak: Support Clang stack depth tracking
In reply to Kees CookWire up CONFIG_STACKLEAK 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.stackleak | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-)
security/Kconfig.hardening +4 -1
@@ -158,10 +158,13 @@ config GCC_PLUGIN_STRUCTLEAK_VERBOSE initialized. Since not all existing initializers are detected by the plugin, this can produce false positive warnings. +config CC_HAS_SANCOV_STACK_DEPTH_CALLBACK + def_bool $(cc-option,-fsanitize-coverage-stack-depth-callback-min=1) + config STACKLEAK bool "Poison kernel stack before returning from syscalls" depends on HAVE_ARCH_STACKLEAK - 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.stackleak +6 -0
@@ -8,6 +8,12 @@ stackleak-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK_VERBOSE) += -fplugin-arg-stacklea DISABLE_STACKLEAK := -fplugin-arg-stackleak_plugin-disable endif +ifdef CONFIG_CC_IS_CLANG +stackleak-cflags-y += -fsanitize-coverage=stack-depth +stackleak-cflags-y += -fsanitize-coverage-stack-depth-callback-min=$(CONFIG_STACKLEAK_TRACK_MIN_SIZE) +DISABLE_STACKLEAK := -fno-sanitize-coverage=stack-depth +endif + STACKLEAK_CFLAGS := $(stackleak-cflags-y) export STACKLEAK_CFLAGS DISABLE_STACKLEAK
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH 7/8 configs/hardening: Enable CONFIG_STACKLEAK
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_STACKLEAK=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 8/8 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