History

gcc-plugins: arm-ssp: Prepare for THREAD_INFO_IN_TASK support

We will be enabling THREAD_INFO_IN_TASK support for ARM, which means that we can no longer load the stack canary value by masking the stack pointer and taking the copy that lives in thread_info. Instead, we will be able to load it from the task_struct directly, by using the TPIDRURO register which will hold the current task pointer when THREAD_INFO_IN_TASK is in effect. This is much more straight-forward, and allows us to declutter this code a bit while at it. Note that this means that ARMv6 (non-v6K) SMP systems can no longer use this feature, but those are quite rare to begin with, so this is a reasonable trade off.

Ard Biesheuvel committed 5 years ago

Commit dfbdcda1 parent 6880fa67 files · +8 −39Browse files

Showing the changes to scripts (1 of 7 files). Show all

Unified · Split

scripts/gcc-plugins/arm_ssp_per_task_plugin.c+6−21
@@ -4,7 +4,7 @@ · 3 unmodified lines
4 4
5__visible int plugin_is_GPL_compatible;5__visible int plugin_is_GPL_compatible;
6 6
7static unsigned int sp_mask, canary_offset;7static unsigned int canary_offset;
8 8
9static unsigned int arm_pertask_ssp_rtl_execute(void)9static unsigned int arm_pertask_ssp_rtl_execute(void)
10{10{
@@ -13,7 +13,7 @@ static unsigned int arm_pertask_ssp_rtl_execute(void) · 2 unmodified lines
13 for (insn = get_insns(); insn; insn = NEXT_INSN(insn)) {13 for (insn = get_insns(); insn; insn = NEXT_INSN(insn)) {
14 const char *sym;14 const char *sym;
15 rtx body;15 rtx body;
16 rtx mask, masked_sp;16 rtx current;
17 17
18 /*18 /*
19 * Find a SET insn involving a SYMBOL_REF to __stack_chk_guard19 * Find a SET insn involving a SYMBOL_REF to __stack_chk_guard
@@ -30,19 +30,13 @@ static unsigned int arm_pertask_ssp_rtl_execute(void) · 10 unmodified lines
30 30
31 /*31 /*
32 * Replace the source of the SET insn with an expression that32 * Replace the source of the SET insn with an expression that
33 * produces the address of the copy of the stack canary value33 * produces the address of the current task's stack canary value
34 * stored in struct thread_info
35 */34 */
36 mask = GEN_INT(sext_hwi(sp_mask, GET_MODE_PRECISION(Pmode)));35 current = gen_reg_rtx(Pmode);
37 masked_sp = gen_reg_rtx(Pmode);
38 36
39 emit_insn_before(gen_rtx_set(masked_sp,37 emit_insn_before(gen_load_tp_hard(current), insn);
40 gen_rtx_AND(Pmode,
41 stack_pointer_rtx,
42 mask)),
43 insn);
44 38
45 SET_SRC(body) = gen_rtx_PLUS(Pmode, masked_sp,39 SET_SRC(body) = gen_rtx_PLUS(Pmode, current,
46 GEN_INT(canary_offset));40 GEN_INT(canary_offset));
47 }41 }
48 return 0;42 return 0;
@@ -72,7 +66,6 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, · 23 unmodified lines
72 const char * const plugin_name = plugin_info->base_name;66 const char * const plugin_name = plugin_info->base_name;
73 const int argc = plugin_info->argc;67 const int argc = plugin_info->argc;
74 const struct plugin_argument *argv = plugin_info->argv;68 const struct plugin_argument *argv = plugin_info->argv;
75 int tso = 0;
76 int i;69 int i;
77 70
78 if (!plugin_default_version_check(version, &gcc_version)) {71 if (!plugin_default_version_check(version, &gcc_version)) {
@@ -91,11 +84,6 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, · 12 unmodified lines
91 return 1;84 return 1;
92 }85 }
93 86
94 if (!strcmp(argv[i].key, "tso")) {
95 tso = atoi(argv[i].value);
96 continue;
97 }
98
99 if (!strcmp(argv[i].key, "offset")) {87 if (!strcmp(argv[i].key, "offset")) {
100 canary_offset = atoi(argv[i].value);88 canary_offset = atoi(argv[i].value);
101 continue;89 continue;
@@ -105,9 +93,6 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, · 3 unmodified lines
105 return 1;93 return 1;
106 }94 }
107 95
108 /* create the mask that produces the base of the stack */
109 sp_mask = ~((1U << (12 + tso)) - 1);
110
111 PASS_INFO(arm_pertask_ssp_rtl, "expand", 1, PASS_POS_INSERT_AFTER);96 PASS_INFO(arm_pertask_ssp_rtl, "expand", 1, PASS_POS_INSERT_AFTER);
112 97
113 register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP,98 register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP,