From a736c81a010a895abc24111c8b9578253215c992 Mon Sep 17 00:00:00 2001 From: Gregory Fong Date: Mon, 17 Jun 2013 19:36:07 +0000 Subject: [PATCH] MIPS: r4k,octeon,r2300: stack protector: change canary per task For non-SMP, uses the new random canary value that is stored in the task struct whenever a new task is forked. Based on ARM version in 8b499865a09290cb8945b8923c7bbf6edacff417 and subject to the same limitations: the variable GCC expects, __stack_chk_guard, is global, so this will not work on SMP. Quoting Nicolas Pitre : "One way to overcome this GCC limitation would be to locate the __stack_chk_guard variable into a memory page of its own for each CPU, and then use TLB locking to have each CPU see its own page at the same virtual address for each of them." Signed-off-by: Gregory Fong Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/5488/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/asm-offsets.c | 3 +++ arch/mips/kernel/octeon_switch.S | 7 +++++++ arch/mips/kernel/r2300_switch.S | 7 +++++++ arch/mips/kernel/r4k_switch.S | 6 ++++++ 4 files changed, 23 insertions(+) diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 0845091ba480b..0c2e853c3db46 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -82,6 +82,9 @@ void output_task_defines(void) OFFSET(TASK_FLAGS, task_struct, flags); OFFSET(TASK_MM, task_struct, mm); OFFSET(TASK_PID, task_struct, pid); +#if defined(CONFIG_CC_STACKPROTECTOR) + OFFSET(TASK_STACK_CANARY, task_struct, stack_canary); +#endif DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct)); BLANK(); } diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S index 22e2aa1e8d373..4204d76af8542 100644 --- a/arch/mips/kernel/octeon_switch.S +++ b/arch/mips/kernel/octeon_switch.S @@ -71,6 +71,13 @@ mtc0 t0, $11,7 /* CvmMemCtl */ #endif 3: + +#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP) + PTR_L t8, __stack_chk_guard + LONG_L t9, TASK_STACK_CANARY(a1) + LONG_S t9, 0(t8) +#endif + /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 5266c6ee2b358..38af83f84c4af 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -65,6 +65,13 @@ LEAF(resume) fpu_save_single a0, t0 # clobbers t0 1: + +#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP) + PTR_L t8, __stack_chk_guard + LONG_L t9, TASK_STACK_CANARY(a1) + LONG_S t9, 0(t8) +#endif + /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 5e51219990aa0..921238a6bd260 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -68,6 +68,12 @@ # clobbers t1 1: +#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP) + PTR_L t8, __stack_chk_guard + LONG_L t9, TASK_STACK_CANARY(a1) + LONG_S t9, 0(t8) +#endif + /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. -- 2.39.5