[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20211021165119.2136543-1-ardb@kernel.org>
Date: Thu, 21 Oct 2021 18:51:18 +0200
From: Ard Biesheuvel <ardb@...nel.org>
To: linux-hardening@...r.kernel.org
Cc: keescook@...omium.org, Ard Biesheuvel <ardb@...nel.org>,
Keith Packard <keithpac@...zon.com>,
thomas.preudhomme@...est.fr, adhemerval.zanella@...aro.org,
Qing Zhao <qing.zhao@...cle.com>,
Richard Sandiford <richard.sandiford@....com>,
gcc-patches@....gnu.org
Subject: [RFC PATCH v2 0/1] implement TLS register based stack canary for ARM
Bugzilla: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102352
In the Linux kernel, user processes calling into the kernel are
essentially threads running in the same address space, of a program that
never terminates. This means that using a global variable for the stack
protector canary value is problematic on SMP systems, as we can never
change it unless we reboot the system. (Processes that sleep for any
reason will do so on a call into the kernel, which means that there will
always be live kernel stack frames carrying copies of the canary taken
when the function was entered)
AArch64 implements -mstack-protector-guard=sysreg for this purpose, as
this permits the kernel to use different memory addresses for the stack
canary for each CPU, and context switch the chosen system register with
the rest of the process, allowing each process to use its own unique
value for the stack canary.
This patch implements something similar, but for the 32-bit ARM kernel,
which will start using the user space TLS register TPIDRURO to index
per-process metadata while running in the kernel. This means we can just
add an offset to TPIDRURO to obtain the address from which to load the
canary value.
As for the spilling issues that have been fixed in this code in the
past: I suppose a register carrying the TLS register value will never
get spilled to begin with?
Comments/suggestions welcome.
Cc: Keith Packard <keithpac@...zon.com>
Cc: thomas.preudhomme@...est.fr
Cc: adhemerval.zanella@...aro.org
Cc: Qing Zhao <qing.zhao@...cle.com>
Cc: Richard Sandiford <richard.sandiford@....com>
Cc: gcc-patches@....gnu.org
Ard Biesheuvel (1):
[ARM] Add support for TLS register based stack protector canary access
gcc/config/arm/arm-opts.h | 6 ++
gcc/config/arm/arm-protos.h | 2 +
gcc/config/arm/arm.c | 52 ++++++++++++++++
gcc/config/arm/arm.md | 62 +++++++++++++++++++-
gcc/config/arm/arm.opt | 22 +++++++
gcc/doc/invoke.texi | 9 +++
6 files changed, 151 insertions(+), 2 deletions(-)
--
2.30.2
$ cat|arm-linux-gnueabihf-gcc -march=armv7-a -mstack-protector-guard=tls -mstack-protector-guard-offset=1296 -mtp=cp15 -S -o - -xc - -fstack-protector-all -O3
int foo(void *);
int bar(void)
{
return foo(__builtin_thread_pointer()) + 1;
}
.arch armv7-a
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 2
.eabi_attribute 34, 1
.eabi_attribute 18, 4
.file "<stdin>"
.text
.align 2
.global bar
.syntax unified
.arm
.type bar, %function
bar:
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 0, uses_anonymous_args = 0
push {r4, lr}
mrc p15, 0, r4, c13, c0, 3 @ load_tp_hard
mov r0, r4
sub sp, sp, #8
ldr r3, [r4, #1296]
str r3, [sp, #4]
mov r3, #0
bl foo
ldr r2, [sp, #4]
ldr r3, [r4, #1296]
eors r3, r2, r3
mov r2, #0
bne .L5
add r0, r0, #1
add sp, sp, #8
@ sp needed
pop {r4, pc}
.L5:
bl __stack_chk_fail
.size bar, .-bar
.ident "GCC: (GNU) 12.0.0 20211021 (experimental)"
.section .note.GNU-stack,"",%progbits
Powered by blists - more mailing lists