Merge tag 'hardening-v6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull hardening updates from Kees Cook: - Introduce and start using TRAILING_OVERLAP() helper for fixing embedded flex array instances (Gustavo A. R. Silva) - mux: Convert mux_control_ops to a flex array member in mux_chip (Thorsten Blum) - string: Group str_has_prefix() and strstarts() (Andy Shevchenko) - Remove KCOV instrumentation from __init and __head (Ritesh Harjani, Kees Cook) - Refactor and rename stackleak feature to support Clang - Add KUnit test for seq_buf API - Fix KUnit fortify test under LTO * tag 'hardening-v6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: (22 commits) sched/task_stack: Add missing const qualifier to end_of_stack() kstack_erase: Support Clang stack depth tracking kstack_erase: Add -mgeneral-regs-only to silence Clang warnings init.h: Disable sanitizer coverage for __init and __head kstack_erase: Disable kstack_erase for all of arm compressed boot code x86: Handle KCOV __init vs inline mismatches arm64: Handle KCOV __init vs inline mismatches s390: Handle KCOV __init vs inline mismatches arm: Handle KCOV __init vs inline mismatches mips: Handle KCOV __init vs inline mismatch powerpc/mm/book3s64: Move kfence and debug_pagealloc related calls to __init section configs/hardening: Enable CONFIG_INIT_ON_FREE_DEFAULT_ON configs/hardening: Enable CONFIG_KSTACK_ERASE stackleak: Split KSTACK_ERASE_CFLAGS from GCC_PLUGINS_CFLAGS stackleak: Rename stackleak_track_stack to __sanitizer_cov_stack_depth stackleak: Rename STACKLEAK to KSTACK_ERASE seq_buf: Introduce KUnit tests string: Group str_has_prefix() and strstarts() kunit/fortify: Add back "volatile" for sizeof() constants acpi: nfit: intel: avoid multiple -Wflex-array-member-not-at-end warnings ...
This commit is contained in:
@@ -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_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
|
||||
export DISABLE_STACKLEAK_PLUGIN
|
||||
|
||||
# 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.
|
||||
|
||||
21
scripts/Makefile.kstack_erase
Normal file
21
scripts/Makefile.kstack_erase
Normal file
@@ -0,0 +1,21 @@
|
||||
# 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
|
||||
|
||||
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
|
||||
|
||||
KBUILD_CFLAGS += $(KSTACK_ERASE_CFLAGS)
|
||||
@@ -9,7 +9,7 @@
|
||||
* any of the gcc libraries
|
||||
*
|
||||
* This gcc plugin is needed for tracking the lowest border of the kernel stack.
|
||||
* It instruments the kernel code inserting stackleak_track_stack() calls:
|
||||
* It instruments the kernel code inserting __sanitizer_cov_stack_depth() calls:
|
||||
* - after alloca();
|
||||
* - for the functions with a stack frame size greater than or equal
|
||||
* to the "track-min-size" plugin parameter.
|
||||
@@ -33,7 +33,7 @@ __visible int plugin_is_GPL_compatible;
|
||||
|
||||
static int track_frame_size = -1;
|
||||
static bool build_for_x86 = false;
|
||||
static const char track_function[] = "stackleak_track_stack";
|
||||
static const char track_function[] = "__sanitizer_cov_stack_depth";
|
||||
static bool disable = false;
|
||||
static bool verbose = false;
|
||||
|
||||
@@ -58,7 +58,7 @@ static void add_stack_tracking_gcall(gimple_stmt_iterator *gsi, bool after)
|
||||
cgraph_node_ptr node;
|
||||
basic_block bb;
|
||||
|
||||
/* Insert calling stackleak_track_stack() */
|
||||
/* Insert calling __sanitizer_cov_stack_depth() */
|
||||
stmt = gimple_build_call(track_function_decl, 0);
|
||||
gimple_call = as_a_gcall(stmt);
|
||||
if (after)
|
||||
@@ -120,12 +120,12 @@ static void add_stack_tracking_gasm(gimple_stmt_iterator *gsi, bool after)
|
||||
gcc_assert(build_for_x86);
|
||||
|
||||
/*
|
||||
* Insert calling stackleak_track_stack() in asm:
|
||||
* asm volatile("call stackleak_track_stack"
|
||||
* Insert calling __sanitizer_cov_stack_depth() in asm:
|
||||
* asm volatile("call __sanitizer_cov_stack_depth"
|
||||
* :: "r" (current_stack_pointer))
|
||||
* Use ASM_CALL_CONSTRAINT trick from arch/x86/include/asm/asm.h.
|
||||
* This constraint is taken into account during gcc shrink-wrapping
|
||||
* optimization. It is needed to be sure that stackleak_track_stack()
|
||||
* optimization. It is needed to be sure that __sanitizer_cov_stack_depth()
|
||||
* call is inserted after the prologue of the containing function,
|
||||
* when the stack frame is prepared.
|
||||
*/
|
||||
@@ -137,7 +137,7 @@ static void add_stack_tracking_gasm(gimple_stmt_iterator *gsi, bool after)
|
||||
input = build_tree_list(NULL_TREE, build_const_char_string(2, "r"));
|
||||
input = chainon(NULL_TREE, build_tree_list(input, sp_decl));
|
||||
vec_safe_push(inputs, input);
|
||||
asm_call = gimple_build_asm_vec("call stackleak_track_stack",
|
||||
asm_call = gimple_build_asm_vec("call __sanitizer_cov_stack_depth",
|
||||
inputs, NULL, NULL, NULL);
|
||||
gimple_asm_set_volatile(asm_call, true);
|
||||
if (after)
|
||||
@@ -151,11 +151,11 @@ static void add_stack_tracking(gimple_stmt_iterator *gsi, bool after)
|
||||
{
|
||||
/*
|
||||
* The 'no_caller_saved_registers' attribute is used for
|
||||
* stackleak_track_stack(). If the compiler supports this attribute for
|
||||
* the target arch, we can add calling stackleak_track_stack() in asm.
|
||||
* __sanitizer_cov_stack_depth(). If the compiler supports this attribute for
|
||||
* the target arch, we can add calling __sanitizer_cov_stack_depth() in asm.
|
||||
* That improves performance: we avoid useless operations with the
|
||||
* caller-saved registers in the functions from which we will remove
|
||||
* stackleak_track_stack() call during the stackleak_cleanup pass.
|
||||
* __sanitizer_cov_stack_depth() call during the stackleak_cleanup pass.
|
||||
*/
|
||||
if (lookup_attribute_spec(get_identifier("no_caller_saved_registers")))
|
||||
add_stack_tracking_gasm(gsi, after);
|
||||
@@ -165,7 +165,7 @@ static void add_stack_tracking(gimple_stmt_iterator *gsi, bool after)
|
||||
|
||||
/*
|
||||
* Work with the GIMPLE representation of the code. Insert the
|
||||
* stackleak_track_stack() call after alloca() and into the beginning
|
||||
* __sanitizer_cov_stack_depth() call after alloca() and into the beginning
|
||||
* of the function if it is not instrumented.
|
||||
*/
|
||||
static unsigned int stackleak_instrument_execute(void)
|
||||
@@ -205,7 +205,7 @@ static unsigned int stackleak_instrument_execute(void)
|
||||
DECL_NAME_POINTER(current_function_decl));
|
||||
}
|
||||
|
||||
/* Insert stackleak_track_stack() call after alloca() */
|
||||
/* Insert __sanitizer_cov_stack_depth() call after alloca() */
|
||||
add_stack_tracking(&gsi, true);
|
||||
if (bb == entry_bb)
|
||||
prologue_instrumented = true;
|
||||
@@ -241,7 +241,7 @@ static unsigned int stackleak_instrument_execute(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Insert stackleak_track_stack() call at the function beginning */
|
||||
/* Insert __sanitizer_cov_stack_depth() call at the function beginning */
|
||||
bb = entry_bb;
|
||||
if (!single_pred_p(bb)) {
|
||||
/* gcc_assert(bb_loop_depth(bb) ||
|
||||
@@ -270,15 +270,15 @@ static void remove_stack_tracking_gcall(void)
|
||||
rtx_insn *insn, *next;
|
||||
|
||||
/*
|
||||
* Find stackleak_track_stack() calls. Loop through the chain of insns,
|
||||
* Find __sanitizer_cov_stack_depth() calls. Loop through the chain of insns,
|
||||
* which is an RTL representation of the code for a function.
|
||||
*
|
||||
* The example of a matching insn:
|
||||
* (call_insn 8 4 10 2 (call (mem (symbol_ref ("stackleak_track_stack")
|
||||
* [flags 0x41] <function_decl 0x7f7cd3302a80 stackleak_track_stack>)
|
||||
* [0 stackleak_track_stack S1 A8]) (0)) 675 {*call} (expr_list
|
||||
* (symbol_ref ("stackleak_track_stack") [flags 0x41] <function_decl
|
||||
* 0x7f7cd3302a80 stackleak_track_stack>) (expr_list (0) (nil))) (nil))
|
||||
* (call_insn 8 4 10 2 (call (mem (symbol_ref ("__sanitizer_cov_stack_depth")
|
||||
* [flags 0x41] <function_decl 0x7f7cd3302a80 __sanitizer_cov_stack_depth>)
|
||||
* [0 __sanitizer_cov_stack_depth S1 A8]) (0)) 675 {*call} (expr_list
|
||||
* (symbol_ref ("__sanitizer_cov_stack_depth") [flags 0x41] <function_decl
|
||||
* 0x7f7cd3302a80 __sanitizer_cov_stack_depth>) (expr_list (0) (nil))) (nil))
|
||||
*/
|
||||
for (insn = get_insns(); insn; insn = next) {
|
||||
rtx body;
|
||||
@@ -318,7 +318,7 @@ static void remove_stack_tracking_gcall(void)
|
||||
if (SYMBOL_REF_DECL(body) != track_function_decl)
|
||||
continue;
|
||||
|
||||
/* Delete the stackleak_track_stack() call */
|
||||
/* Delete the __sanitizer_cov_stack_depth() call */
|
||||
delete_insn_and_edges(insn);
|
||||
#if BUILDING_GCC_VERSION < 8000
|
||||
if (GET_CODE(next) == NOTE &&
|
||||
@@ -340,12 +340,12 @@ static bool remove_stack_tracking_gasm(void)
|
||||
gcc_assert(build_for_x86);
|
||||
|
||||
/*
|
||||
* Find stackleak_track_stack() asm calls. Loop through the chain of
|
||||
* Find __sanitizer_cov_stack_depth() asm calls. Loop through the chain of
|
||||
* insns, which is an RTL representation of the code for a function.
|
||||
*
|
||||
* The example of a matching insn:
|
||||
* (insn 11 5 12 2 (parallel [ (asm_operands/v
|
||||
* ("call stackleak_track_stack") ("") 0
|
||||
* ("call __sanitizer_cov_stack_depth") ("") 0
|
||||
* [ (reg/v:DI 7 sp [ current_stack_pointer ]) ]
|
||||
* [ (asm_input:DI ("r")) ] [])
|
||||
* (clobber (reg:CC 17 flags)) ]) -1 (nil))
|
||||
@@ -375,7 +375,7 @@ static bool remove_stack_tracking_gasm(void)
|
||||
continue;
|
||||
|
||||
if (strcmp(ASM_OPERANDS_TEMPLATE(body),
|
||||
"call stackleak_track_stack")) {
|
||||
"call __sanitizer_cov_stack_depth")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -389,7 +389,7 @@ static bool remove_stack_tracking_gasm(void)
|
||||
|
||||
/*
|
||||
* Work with the RTL representation of the code.
|
||||
* Remove the unneeded stackleak_track_stack() calls from the functions
|
||||
* Remove the unneeded __sanitizer_cov_stack_depth() calls from the functions
|
||||
* which don't call alloca() and don't have a large enough stack frame size.
|
||||
*/
|
||||
static unsigned int stackleak_cleanup_execute(void)
|
||||
@@ -474,13 +474,13 @@ static bool stackleak_gate(void)
|
||||
return track_frame_size >= 0;
|
||||
}
|
||||
|
||||
/* Build the function declaration for stackleak_track_stack() */
|
||||
/* Build the function declaration for __sanitizer_cov_stack_depth() */
|
||||
static void stackleak_start_unit(void *gcc_data __unused,
|
||||
void *user_data __unused)
|
||||
{
|
||||
tree fntype;
|
||||
|
||||
/* void stackleak_track_stack(void) */
|
||||
/* void __sanitizer_cov_stack_depth(void) */
|
||||
fntype = build_function_type_list(void_type_node, NULL_TREE);
|
||||
track_function_decl = build_fn_decl(track_function, fntype);
|
||||
DECL_ASSEMBLER_NAME(track_function_decl); /* for LTO */
|
||||
|
||||
Reference in New Issue
Block a user