hardening updates for v5.18-rc1
- Add arm64 Shadow Call Stack support for GCC 12 (Dan Li) - Avoid memset with stack offset randomization under Clang (Marco Elver) - Clean up stackleak plugin to play nice with .noinstr (Kees Cook) - Check stack depth for greater usercopy hardening coverage (Kees Cook) -----BEGIN PGP SIGNATURE----- iQJKBAABCgA0FiEEpcP2jyKd1g9yPm4TiXL039xtwCYFAmI4kXMWHGtlZXNjb29r QGNocm9taXVtLm9yZwAKCRCJcvTf3G3AJhBoD/wJFr0s13Cvsbibuk7PLAPJlQe9 QBMolrrS9+JNoqdIMiILrmthCPnDBkBNrU/YvfkIyGQOO2RGxrtZVzLhyHKCDg6u iIkNG9S5D12ucEdqqLWdZxyBZcQuR6Rf//lGvtx8ps+jYy8fDwRekurJIb3kWl5u qB0O0PFd+RjGgvtm+Fh8h0FiBMxbKfPXI+s7W2rCfcwe+w5Z24YD1eoCHmnQJYcu Mnuk7cHsx2TFms4UqUK1Z/0EBpCKNEEX4s0z/nrfu8dRTPvLqLgbGpcmXTkik9PN BucIxgdRqqYbTyGvhsDhpEUVfmFcQzdPmuMnnnUc8BiXy9EqGqSfjMEzutuf+RS7 0i4LWoDW2LYMUixqDLAMdLpwdC2Ca7hP62kE4vNVqW3jBty+jhPBVO6ddhHO14nd q6m+CQz0SVTIyrLI4N+TNg/EIj2DpBpAhs49QWDOL/ZqP0ewYk8Ef8pXKgJo2jJC aAs+18pdpoVCEs1fztzjuWZT77iTmziYhb2BOMnT4yBcAdifi7eW6l0pYsgfxoJ/ WC/MmTWt08/IHBk09d8GbFdoP8byDUgzmzUUoskJJH2JA7475xM6qhI2J627Lpth baEv3UT8JWBBX+koU2wxhxKgscIvbNjJjpEGNt2YuBBeQ4lrlijsFzQjmu62gZDL LG0XOVV97/1V9uJ2CA== =yaWZ -----END PGP SIGNATURE----- Merge tag 'hardening-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux Pull kernel hardening updates from Kees Cook: - Add arm64 Shadow Call Stack support for GCC 12 (Dan Li) - Avoid memset with stack offset randomization under Clang (Marco Elver) - Clean up stackleak plugin to play nice with .noinstr (Kees Cook) - Check stack depth for greater usercopy hardening coverage (Kees Cook) * tag 'hardening-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: arm64: Add gcc Shadow Call Stack support m68k: Implement "current_stack_pointer" xtensa: Implement "current_stack_pointer" usercopy: Check valid lifetime via stack depth stack: Constrain and fix stack offset randomization with Clang builds stack: Introduce CONFIG_RANDOMIZE_KSTACK_OFFSET gcc-plugins/stackleak: Ignore .noinstr.text and .entry.text gcc-plugins/stackleak: Exactly match strings instead of prefixes gcc-plugins/stackleak: Provide verbose mode
This commit is contained in:
commit
2142b7f0c6
43
arch/Kconfig
43
arch/Kconfig
|
@ -599,21 +599,22 @@ config STACKPROTECTOR_STRONG
|
|||
config ARCH_SUPPORTS_SHADOW_CALL_STACK
|
||||
bool
|
||||
help
|
||||
An architecture should select this if it supports Clang's Shadow
|
||||
Call Stack and implements runtime support for shadow stack
|
||||
An architecture should select this if it supports the compiler's
|
||||
Shadow Call Stack and implements runtime support for shadow stack
|
||||
switching.
|
||||
|
||||
config SHADOW_CALL_STACK
|
||||
bool "Clang Shadow Call Stack"
|
||||
depends on CC_IS_CLANG && ARCH_SUPPORTS_SHADOW_CALL_STACK
|
||||
bool "Shadow Call Stack"
|
||||
depends on ARCH_SUPPORTS_SHADOW_CALL_STACK
|
||||
depends on DYNAMIC_FTRACE_WITH_REGS || !FUNCTION_GRAPH_TRACER
|
||||
help
|
||||
This option enables Clang's Shadow Call Stack, which uses a
|
||||
shadow stack to protect function return addresses from being
|
||||
overwritten by an attacker. More information can be found in
|
||||
Clang's documentation:
|
||||
This option enables the compiler's Shadow Call Stack, which
|
||||
uses a shadow stack to protect function return addresses from
|
||||
being overwritten by an attacker. More information can be found
|
||||
in the compiler's documentation:
|
||||
|
||||
https://clang.llvm.org/docs/ShadowCallStack.html
|
||||
- Clang: https://clang.llvm.org/docs/ShadowCallStack.html
|
||||
- GCC: https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#Instrumentation-Options
|
||||
|
||||
Note that security guarantees in the kernel differ from the
|
||||
ones documented for user space. The kernel must store addresses
|
||||
|
@ -1159,16 +1160,30 @@ config HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
|
|||
to the compiler, so it will attempt to add canary checks regardless
|
||||
of the static branch state.
|
||||
|
||||
config RANDOMIZE_KSTACK_OFFSET_DEFAULT
|
||||
bool "Randomize kernel stack offset on syscall entry"
|
||||
config RANDOMIZE_KSTACK_OFFSET
|
||||
bool "Support for randomizing kernel stack offset on syscall entry" if EXPERT
|
||||
default y
|
||||
depends on HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
|
||||
depends on INIT_STACK_NONE || !CC_IS_CLANG || CLANG_VERSION >= 140000
|
||||
help
|
||||
The kernel stack offset can be randomized (after pt_regs) by
|
||||
roughly 5 bits of entropy, frustrating memory corruption
|
||||
attacks that depend on stack address determinism or
|
||||
cross-syscall address exposures. This feature is controlled
|
||||
by kernel boot param "randomize_kstack_offset=on/off", and this
|
||||
config chooses the default boot state.
|
||||
cross-syscall address exposures.
|
||||
|
||||
The feature is controlled via the "randomize_kstack_offset=on/off"
|
||||
kernel boot param, and if turned off has zero overhead due to its use
|
||||
of static branches (see JUMP_LABEL).
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config RANDOMIZE_KSTACK_OFFSET_DEFAULT
|
||||
bool "Default state of kernel stack offset randomization"
|
||||
depends on RANDOMIZE_KSTACK_OFFSET
|
||||
help
|
||||
Kernel stack offset randomization is controlled by kernel boot param
|
||||
"randomize_kstack_offset=on/off", and this config chooses the default
|
||||
boot state.
|
||||
|
||||
config ARCH_OPTIONAL_KERNEL_RWX
|
||||
def_bool n
|
||||
|
|
|
@ -5,6 +5,7 @@ config ARM
|
|||
select ARCH_32BIT_OFF_T
|
||||
select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND
|
||||
select ARCH_HAS_BINFMT_FLAT
|
||||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_DEBUG_VIRTUAL if MMU
|
||||
select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
|
||||
select ARCH_HAS_ELF_RANDOMIZE
|
||||
|
|
|
@ -19,6 +19,7 @@ config ARM64
|
|||
select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
|
||||
select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
|
||||
select ARCH_HAS_CACHE_LINE_SIZE
|
||||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_DEBUG_VIRTUAL
|
||||
select ARCH_HAS_DEBUG_VM_PGTABLE
|
||||
select ARCH_HAS_DMA_PREP_COHERENT
|
||||
|
@ -1257,7 +1258,7 @@ config HW_PERF_EVENTS
|
|||
def_bool y
|
||||
depends on ARM_PMU
|
||||
|
||||
# Supported by clang >= 7.0
|
||||
# Supported by clang >= 7.0 or GCC >= 12.0.0
|
||||
config CC_HAVE_SHADOW_CALL_STACK
|
||||
def_bool $(cc-option, -fsanitize=shadow-call-stack -ffixed-x18)
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ config M68K
|
|||
default y
|
||||
select ARCH_32BIT_OFF_T
|
||||
select ARCH_HAS_BINFMT_FLAT
|
||||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE
|
||||
select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
|
||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
|
||||
|
|
|
@ -24,6 +24,8 @@ static inline struct task_struct *get_current(void)
|
|||
|
||||
#define current get_current()
|
||||
|
||||
#endif /* CONFNIG_MMU */
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
register unsigned long current_stack_pointer __asm__("sp");
|
||||
|
||||
#endif /* !(_M68K_CURRENT_H) */
|
||||
|
|
|
@ -108,6 +108,7 @@ config PPC
|
|||
select ARCH_ENABLE_MEMORY_HOTPLUG
|
||||
select ARCH_ENABLE_MEMORY_HOTREMOVE
|
||||
select ARCH_HAS_COPY_MC if PPC64
|
||||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_DEBUG_VIRTUAL
|
||||
select ARCH_HAS_DEBUG_VM_PGTABLE
|
||||
select ARCH_HAS_DEBUG_WX if STRICT_KERNEL_RWX
|
||||
|
|
|
@ -60,6 +60,7 @@ config S390
|
|||
select ARCH_ENABLE_MEMORY_HOTPLUG if SPARSEMEM
|
||||
select ARCH_ENABLE_MEMORY_HOTREMOVE
|
||||
select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
|
||||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_DEBUG_VM_PGTABLE
|
||||
select ARCH_HAS_DEBUG_WX
|
||||
select ARCH_HAS_DEVMEM_IS_ALLOWED
|
||||
|
|
|
@ -7,6 +7,7 @@ config SUPERH
|
|||
select ARCH_HAVE_CUSTOM_GPIO_H
|
||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A)
|
||||
select ARCH_HAS_BINFMT_FLAT if !MMU
|
||||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_GIGANTIC_PAGE
|
||||
select ARCH_HAS_GCOV_PROFILE_ALL
|
||||
select ARCH_HAS_PTE_SPECIAL
|
||||
|
|
|
@ -69,6 +69,7 @@ config X86
|
|||
select ARCH_ENABLE_THP_MIGRATION if X86_64 && TRANSPARENT_HUGEPAGE
|
||||
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
|
||||
select ARCH_HAS_CACHE_LINE_SIZE
|
||||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_DEBUG_VIRTUAL
|
||||
select ARCH_HAS_DEBUG_VM_PGTABLE if !X86_PAE
|
||||
select ARCH_HAS_DEVMEM_IS_ALLOWED
|
||||
|
|
|
@ -3,6 +3,7 @@ config XTENSA
|
|||
def_bool y
|
||||
select ARCH_32BIT_OFF_T
|
||||
select ARCH_HAS_BINFMT_FLAT if !MMU
|
||||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_DMA_PREP_COHERENT if MMU
|
||||
select ARCH_HAS_SYNC_DMA_FOR_CPU if MMU
|
||||
select ARCH_HAS_SYNC_DMA_FOR_DEVICE if MMU
|
||||
|
|
|
@ -26,6 +26,8 @@ static inline struct task_struct *get_current(void)
|
|||
|
||||
#define current get_current()
|
||||
|
||||
register unsigned long current_stack_pointer __asm__("a1");
|
||||
|
||||
#else
|
||||
|
||||
#define GET_CURRENT(reg,sp) \
|
||||
|
|
|
@ -19,14 +19,14 @@ struct stackframe {
|
|||
|
||||
static __always_inline unsigned long *stack_pointer(struct task_struct *task)
|
||||
{
|
||||
unsigned long *sp;
|
||||
unsigned long sp;
|
||||
|
||||
if (!task || task == current)
|
||||
__asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp));
|
||||
sp = current_stack_pointer;
|
||||
else
|
||||
sp = (unsigned long *)task->thread.sp;
|
||||
sp = task->thread.sp;
|
||||
|
||||
return sp;
|
||||
return (unsigned long *)sp;
|
||||
}
|
||||
|
||||
void walk_stackframe(unsigned long *sp,
|
||||
|
|
|
@ -36,9 +36,8 @@ asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
|
|||
#ifdef CONFIG_DEBUG_STACKOVERFLOW
|
||||
/* Debugging check for stack overflow: is there less than 1KB free? */
|
||||
{
|
||||
unsigned long sp;
|
||||
unsigned long sp = current_stack_pointer;
|
||||
|
||||
__asm__ __volatile__ ("mov %0, a1\n" : "=a" (sp));
|
||||
sp &= THREAD_SIZE - 1;
|
||||
|
||||
if (unlikely(sp < (sizeof(thread_info) + 1024)))
|
||||
|
|
|
@ -97,6 +97,10 @@
|
|||
#define KASAN_ABI_VERSION 4
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SHADOW_CALL_STACK
|
||||
#define __noscs __attribute__((__no_sanitize__("shadow-call-stack")))
|
||||
#endif
|
||||
|
||||
#if __has_attribute(__no_sanitize_address__)
|
||||
#define __no_sanitize_address __attribute__((no_sanitize_address))
|
||||
#else
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#ifndef _LINUX_RANDOMIZE_KSTACK_H
|
||||
#define _LINUX_RANDOMIZE_KSTACK_H
|
||||
|
||||
#ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/percpu-defs.h>
|
||||
|
@ -16,8 +17,20 @@ DECLARE_PER_CPU(u32, kstack_offset);
|
|||
* alignment. Also, since this use is being explicitly masked to a max of
|
||||
* 10 bits, stack-clash style attacks are unlikely. For more details see
|
||||
* "VLAs" in Documentation/process/deprecated.rst
|
||||
*
|
||||
* The normal __builtin_alloca() is initialized with INIT_STACK_ALL (currently
|
||||
* only with Clang and not GCC). Initializing the unused area on each syscall
|
||||
* entry is expensive, and generating an implicit call to memset() may also be
|
||||
* problematic (such as in noinstr functions). Therefore, if the compiler
|
||||
* supports it (which it should if it initializes allocas), always use the
|
||||
* "uninitialized" variant of the builtin.
|
||||
*/
|
||||
void *__builtin_alloca(size_t size);
|
||||
#if __has_builtin(__builtin_alloca_uninitialized)
|
||||
#define __kstack_alloca __builtin_alloca_uninitialized
|
||||
#else
|
||||
#define __kstack_alloca __builtin_alloca
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use, at most, 10 bits of entropy. We explicitly cap this to keep the
|
||||
* "VLA" from being unbounded (see above). 10 bits leaves enough room for
|
||||
|
@ -36,7 +49,7 @@ void *__builtin_alloca(size_t size);
|
|||
if (static_branch_maybe(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT, \
|
||||
&randomize_kstack_offset)) { \
|
||||
u32 offset = raw_cpu_read(kstack_offset); \
|
||||
u8 *ptr = __builtin_alloca(KSTACK_OFFSET_MAX(offset)); \
|
||||
u8 *ptr = __kstack_alloca(KSTACK_OFFSET_MAX(offset)); \
|
||||
/* Keep allocation even after "ptr" loses scope. */ \
|
||||
asm volatile("" :: "r"(ptr) : "memory"); \
|
||||
} \
|
||||
|
@ -50,5 +63,9 @@ void *__builtin_alloca(size_t size);
|
|||
raw_cpu_write(kstack_offset, offset); \
|
||||
} \
|
||||
} while (0)
|
||||
#else /* CONFIG_RANDOMIZE_KSTACK_OFFSET */
|
||||
#define add_random_kstack_offset() do { } while (0)
|
||||
#define choose_random_kstack_offset(rand) do { } while (0)
|
||||
#endif /* CONFIG_RANDOMIZE_KSTACK_OFFSET */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -853,7 +853,7 @@ static void __init mm_init(void)
|
|||
pti_init();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
|
||||
#ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET
|
||||
DEFINE_STATIC_KEY_MAYBE_RO(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT,
|
||||
randomize_kstack_offset);
|
||||
DEFINE_PER_CPU(u32, kstack_offset);
|
||||
|
|
|
@ -744,6 +744,15 @@ config IDLE_PAGE_TRACKING
|
|||
config ARCH_HAS_CACHE_LINE_SIZE
|
||||
bool
|
||||
|
||||
config ARCH_HAS_CURRENT_STACK_POINTER
|
||||
bool
|
||||
help
|
||||
In support of HARDENED_USERCOPY performing stack variable lifetime
|
||||
checking, an architecture-agnostic way to find the stack pointer
|
||||
is needed. Once an architecture defines an unsigned long global
|
||||
register alias named "current_stack_pointer", this config can be
|
||||
selected.
|
||||
|
||||
config ARCH_HAS_PTE_DEVMAP
|
||||
bool
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
* Returns:
|
||||
* NOT_STACK: not at all on the stack
|
||||
* GOOD_FRAME: fully within a valid stack frame
|
||||
* GOOD_STACK: fully on the stack (when can't do frame-checking)
|
||||
* GOOD_STACK: within the current stack (when can't frame-check exactly)
|
||||
* BAD_STACK: error condition (invalid stack position or bad stack frame)
|
||||
*/
|
||||
static noinline int check_stack_object(const void *obj, unsigned long len)
|
||||
|
@ -55,6 +55,17 @@ static noinline int check_stack_object(const void *obj, unsigned long len)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Finally, check stack depth if possible. */
|
||||
#ifdef CONFIG_ARCH_HAS_CURRENT_STACK_POINTER
|
||||
if (IS_ENABLED(CONFIG_STACK_GROWSUP)) {
|
||||
if ((void *)current_stack_pointer < obj + len)
|
||||
return BAD_STACK;
|
||||
} else {
|
||||
if (obj < (void *)current_stack_pointer)
|
||||
return BAD_STACK;
|
||||
}
|
||||
#endif
|
||||
|
||||
return GOOD_STACK;
|
||||
}
|
||||
|
||||
|
@ -280,7 +291,15 @@ void __check_object_size(const void *ptr, unsigned long n, bool to_user)
|
|||
*/
|
||||
return;
|
||||
default:
|
||||
usercopy_abort("process stack", NULL, to_user, 0, n);
|
||||
usercopy_abort("process stack", NULL, to_user,
|
||||
#ifdef CONFIG_ARCH_HAS_CURRENT_STACK_POINTER
|
||||
IS_ENABLED(CONFIG_STACK_GROWSUP) ?
|
||||
ptr - (void *)current_stack_pointer :
|
||||
(void *)current_stack_pointer - ptr,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
n);
|
||||
}
|
||||
|
||||
/* Check for bad heap object. */
|
||||
|
|
|
@ -37,6 +37,8 @@ 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_PLUGIN += -fplugin-arg-stackleak_plugin-disable
|
||||
endif
|
||||
|
|
|
@ -429,6 +429,23 @@ static unsigned int stackleak_cleanup_execute(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* STRING_CST may or may not be NUL terminated:
|
||||
* https://gcc.gnu.org/onlinedocs/gccint/Constant-expressions.html
|
||||
*/
|
||||
static inline bool string_equal(tree node, const char *string, int length)
|
||||
{
|
||||
if (TREE_STRING_LENGTH(node) < length)
|
||||
return false;
|
||||
if (TREE_STRING_LENGTH(node) > length + 1)
|
||||
return false;
|
||||
if (TREE_STRING_LENGTH(node) == length + 1 &&
|
||||
TREE_STRING_POINTER(node)[length] != '\0')
|
||||
return false;
|
||||
return !memcmp(TREE_STRING_POINTER(node), string, length);
|
||||
}
|
||||
#define STRING_EQUAL(node, str) string_equal(node, str, strlen(str))
|
||||
|
||||
static bool stackleak_gate(void)
|
||||
{
|
||||
tree section;
|
||||
|
@ -438,13 +455,17 @@ static bool stackleak_gate(void)
|
|||
if (section && TREE_VALUE(section)) {
|
||||
section = TREE_VALUE(TREE_VALUE(section));
|
||||
|
||||
if (!strncmp(TREE_STRING_POINTER(section), ".init.text", 10))
|
||||
if (STRING_EQUAL(section, ".init.text"))
|
||||
return false;
|
||||
if (!strncmp(TREE_STRING_POINTER(section), ".devinit.text", 13))
|
||||
if (STRING_EQUAL(section, ".devinit.text"))
|
||||
return false;
|
||||
if (!strncmp(TREE_STRING_POINTER(section), ".cpuinit.text", 13))
|
||||
if (STRING_EQUAL(section, ".cpuinit.text"))
|
||||
return false;
|
||||
if (!strncmp(TREE_STRING_POINTER(section), ".meminit.text", 13))
|
||||
if (STRING_EQUAL(section, ".meminit.text"))
|
||||
return false;
|
||||
if (STRING_EQUAL(section, ".noinstr.text"))
|
||||
return false;
|
||||
if (STRING_EQUAL(section, ".entry.text"))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -174,6 +174,16 @@ config GCC_PLUGIN_STACKLEAK
|
|||
* https://grsecurity.net/
|
||||
* https://pax.grsecurity.net/
|
||||
|
||||
config GCC_PLUGIN_STACKLEAK_VERBOSE
|
||||
bool "Report stack depth analysis instrumentation" if EXPERT
|
||||
depends on GCC_PLUGIN_STACKLEAK
|
||||
depends on !COMPILE_TEST # too noisy
|
||||
help
|
||||
This option will cause a warning to be printed each time the
|
||||
stackleak plugin finds a function it thinks needs to be
|
||||
instrumented. This is useful for comparing coverage between
|
||||
builds.
|
||||
|
||||
config STACKLEAK_TRACK_MIN_SIZE
|
||||
int "Minimum stack frame size of functions tracked by STACKLEAK"
|
||||
default 100
|
||||
|
|
Loading…
Reference in New Issue