Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gcc-plugins: Remove ARM_SSP_PER_TASK plugin

As part of trying to remove GCC plugins from Linux, drop the
ARM_SSP_PER_TASK plugin. The feature is available upstream since GCC
12, so anyone needing newer kernels with per-task ssp can update their
compiler[1].

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/all/08393aa3-05a3-4e3f-8004-f374a3ec4b7e@app.fastmail.com/ [1]
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20250409160409.work.168-kees@kernel.org
Signed-off-by: Kees Cook <kees@kernel.org>

Kees Cook b8e14797 28cd28a7

+2 -120
+1 -2
arch/arm/Kconfig
··· 1380 1380 config STACKPROTECTOR_PER_TASK 1381 1381 bool "Use a unique stack canary value for each task" 1382 1382 depends on STACKPROTECTOR && CURRENT_POINTER_IN_TPIDRURO && !XIP_DEFLATED_DATA 1383 - depends on GCC_PLUGINS || CC_HAVE_STACKPROTECTOR_TLS 1384 - select GCC_PLUGIN_ARM_SSP_PER_TASK if !CC_HAVE_STACKPROTECTOR_TLS 1383 + depends on CC_HAVE_STACKPROTECTOR_TLS 1385 1384 default y 1386 1385 help 1387 1386 Due to the fact that GCC uses an ordinary symbol reference from
+1 -1
arch/arm/boot/compressed/Makefile
··· 96 96 97 97 ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin \ 98 98 -I$(srctree)/scripts/dtc/libfdt -fno-stack-protector \ 99 - -I$(obj) $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) 99 + -I$(obj) 100 100 ccflags-remove-$(CONFIG_FUNCTION_TRACER) += -pg 101 101 asflags-y := -DZIMAGE 102 102
-6
scripts/Makefile.gcc-plugins
··· 36 36 endif 37 37 export DISABLE_STACKLEAK_PLUGIN 38 38 39 - gcc-plugin-$(CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK) += arm_ssp_per_task_plugin.so 40 - ifdef CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK 41 - DISABLE_ARM_SSP_PER_TASK_PLUGIN += -fplugin-arg-arm_ssp_per_task_plugin-disable 42 - endif 43 - export DISABLE_ARM_SSP_PER_TASK_PLUGIN 44 - 45 39 # All the plugin CFLAGS are collected here in case a build target needs to 46 40 # filter them out of the KBUILD_CFLAGS. 47 41 GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y))
-4
scripts/gcc-plugins/Kconfig
··· 46 46 * https://grsecurity.net/ 47 47 * https://pax.grsecurity.net/ 48 48 49 - config GCC_PLUGIN_ARM_SSP_PER_TASK 50 - bool 51 - depends on GCC_PLUGINS && ARM 52 - 53 49 endif
-107
scripts/gcc-plugins/arm_ssp_per_task_plugin.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - 3 - #include "gcc-common.h" 4 - 5 - __visible int plugin_is_GPL_compatible; 6 - 7 - static unsigned int canary_offset; 8 - 9 - static unsigned int arm_pertask_ssp_rtl_execute(void) 10 - { 11 - rtx_insn *insn; 12 - 13 - for (insn = get_insns(); insn; insn = NEXT_INSN(insn)) { 14 - const char *sym; 15 - rtx body; 16 - rtx current; 17 - 18 - /* 19 - * Find a SET insn involving a SYMBOL_REF to __stack_chk_guard 20 - */ 21 - if (!INSN_P(insn)) 22 - continue; 23 - body = PATTERN(insn); 24 - if (GET_CODE(body) != SET || 25 - GET_CODE(SET_SRC(body)) != SYMBOL_REF) 26 - continue; 27 - sym = XSTR(SET_SRC(body), 0); 28 - if (strcmp(sym, "__stack_chk_guard")) 29 - continue; 30 - 31 - /* 32 - * Replace the source of the SET insn with an expression that 33 - * produces the address of the current task's stack canary value 34 - */ 35 - current = gen_reg_rtx(Pmode); 36 - 37 - emit_insn_before(gen_load_tp_hard(current), insn); 38 - 39 - SET_SRC(body) = gen_rtx_PLUS(Pmode, current, 40 - GEN_INT(canary_offset)); 41 - } 42 - return 0; 43 - } 44 - 45 - #define PASS_NAME arm_pertask_ssp_rtl 46 - 47 - #define NO_GATE 48 - #include "gcc-generate-rtl-pass.h" 49 - 50 - #if BUILDING_GCC_VERSION >= 9000 51 - static bool no(void) 52 - { 53 - return false; 54 - } 55 - 56 - static void arm_pertask_ssp_start_unit(void *gcc_data, void *user_data) 57 - { 58 - targetm.have_stack_protect_combined_set = no; 59 - targetm.have_stack_protect_combined_test = no; 60 - } 61 - #endif 62 - 63 - __visible int plugin_init(struct plugin_name_args *plugin_info, 64 - struct plugin_gcc_version *version) 65 - { 66 - const char * const plugin_name = plugin_info->base_name; 67 - const int argc = plugin_info->argc; 68 - const struct plugin_argument *argv = plugin_info->argv; 69 - int i; 70 - 71 - if (!plugin_default_version_check(version, &gcc_version)) { 72 - error(G_("incompatible gcc/plugin versions")); 73 - return 1; 74 - } 75 - 76 - for (i = 0; i < argc; ++i) { 77 - if (!strcmp(argv[i].key, "disable")) 78 - return 0; 79 - 80 - /* all remaining options require a value */ 81 - if (!argv[i].value) { 82 - error(G_("no value supplied for option '-fplugin-arg-%s-%s'"), 83 - plugin_name, argv[i].key); 84 - return 1; 85 - } 86 - 87 - if (!strcmp(argv[i].key, "offset")) { 88 - canary_offset = atoi(argv[i].value); 89 - continue; 90 - } 91 - error(G_("unknown option '-fplugin-arg-%s-%s'"), 92 - plugin_name, argv[i].key); 93 - return 1; 94 - } 95 - 96 - PASS_INFO(arm_pertask_ssp_rtl, "expand", 1, PASS_POS_INSERT_AFTER); 97 - 98 - register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, 99 - NULL, &arm_pertask_ssp_rtl_pass_info); 100 - 101 - #if BUILDING_GCC_VERSION >= 9000 102 - register_callback(plugin_info->base_name, PLUGIN_START_UNIT, 103 - arm_pertask_ssp_start_unit, NULL); 104 - #endif 105 - 106 - return 0; 107 - }