Skip to content

Commit 082af5e

Browse files
committed
Merge branch 'for-next/scs' into for-next/core
Support for Clang's Shadow Call Stack in the kernel (Sami Tolvanen and Will Deacon) * for-next/scs: arm64: entry-ftrace.S: Update comment to indicate that x18 is live scs: Move DEFINE_SCS macro into core code scs: Remove references to asm/scs.h from core code scs: Move scs_overflow_check() out of architecture code arm64: scs: Use 'scs_sp' register alias for x18 scs: Move accounting into alloc/free functions arm64: scs: Store absolute SCS stack pointer value in thread_info efi/libstub: Disable Shadow Call Stack arm64: scs: Add shadow stacks for SDEI arm64: Implement Shadow Call Stack arm64: Disable SCS for hypervisor code arm64: vdso: Disable Shadow Call Stack arm64: efi: Restore register x18 if it was corrupted arm64: Preserve register x18 when CPU is suspended arm64: Reserve register x18 from general allocation with SCS scs: Disable when function graph tracing is enabled scs: Add support for stack usage debugging scs: Add page accounting for shadow call stack allocations scs: Add support for Clang's Shadow Call Stack (SCS)
2 parents c350717 + 258c3d6 commit 082af5e

File tree

31 files changed

+406
-9
lines changed

31 files changed

+406
-9
lines changed

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,12 @@ ifdef CONFIG_LIVEPATCH
866866
KBUILD_CFLAGS += $(call cc-option, -flive-patching=inline-clone)
867867
endif
868868

869+
ifdef CONFIG_SHADOW_CALL_STACK
870+
CC_FLAGS_SCS := -fsanitize=shadow-call-stack
871+
KBUILD_CFLAGS += $(CC_FLAGS_SCS)
872+
export CC_FLAGS_SCS
873+
endif
874+
869875
# arch Makefile may override CC so keep this after arch Makefile is included
870876
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
871877

arch/Kconfig

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,31 @@ config STACKPROTECTOR_STRONG
533533
about 20% of all kernel functions, which increases the kernel code
534534
size by about 2%.
535535

536+
config ARCH_SUPPORTS_SHADOW_CALL_STACK
537+
bool
538+
help
539+
An architecture should select this if it supports Clang's Shadow
540+
Call Stack and implements runtime support for shadow stack
541+
switching.
542+
543+
config SHADOW_CALL_STACK
544+
bool "Clang Shadow Call Stack"
545+
depends on CC_IS_CLANG && ARCH_SUPPORTS_SHADOW_CALL_STACK
546+
depends on DYNAMIC_FTRACE_WITH_REGS || !FUNCTION_GRAPH_TRACER
547+
help
548+
This option enables Clang's Shadow Call Stack, which uses a
549+
shadow stack to protect function return addresses from being
550+
overwritten by an attacker. More information can be found in
551+
Clang's documentation:
552+
553+
https://clang.llvm.org/docs/ShadowCallStack.html
554+
555+
Note that security guarantees in the kernel differ from the
556+
ones documented for user space. The kernel must store addresses
557+
of shadow stacks in memory, which means an attacker capable of
558+
reading and writing arbitrary memory may be able to locate them
559+
and hijack control flow by modifying the stacks.
560+
536561
config HAVE_ARCH_WITHIN_STACK_FRAMES
537562
bool
538563
help

arch/arm64/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ config ARM64
6868
select ARCH_USE_QUEUED_SPINLOCKS
6969
select ARCH_USE_SYM_ANNOTATIONS
7070
select ARCH_SUPPORTS_MEMORY_FAILURE
71+
select ARCH_SUPPORTS_SHADOW_CALL_STACK if CC_HAVE_SHADOW_CALL_STACK
7172
select ARCH_SUPPORTS_ATOMIC_RMW
7273
select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 && (GCC_VERSION >= 50000 || CC_IS_CLANG)
7374
select ARCH_SUPPORTS_NUMA_BALANCING
@@ -1026,6 +1027,10 @@ config ARCH_HAS_CACHE_LINE_SIZE
10261027
config ARCH_ENABLE_SPLIT_PMD_PTLOCK
10271028
def_bool y if PGTABLE_LEVELS > 2
10281029

1030+
# Supported by clang >= 7.0
1031+
config CC_HAVE_SHADOW_CALL_STACK
1032+
def_bool $(cc-option, -fsanitize=shadow-call-stack -ffixed-x18)
1033+
10291034
config SECCOMP
10301035
bool "Enable seccomp to safely compute untrusted bytecode"
10311036
---help---

arch/arm64/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ endif
8787

8888
KBUILD_CFLAGS += $(branch-prot-flags-y)
8989

90+
ifeq ($(CONFIG_SHADOW_CALL_STACK), y)
91+
KBUILD_CFLAGS += -ffixed-x18
92+
endif
93+
9094
ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
9195
KBUILD_CPPFLAGS += -mbig-endian
9296
CHECKFLAGS += -D__AARCH64EB__

arch/arm64/include/asm/kvm_hyp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include <asm/alternative.h>
1313
#include <asm/sysreg.h>
1414

15-
#define __hyp_text __section(.hyp.text) notrace
15+
#define __hyp_text __section(.hyp.text) notrace __noscs
1616

1717
#define read_sysreg_elx(r,nvh,vh) \
1818
({ \

arch/arm64/include/asm/scs.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef _ASM_SCS_H
3+
#define _ASM_SCS_H
4+
5+
#ifdef __ASSEMBLY__
6+
7+
#include <asm/asm-offsets.h>
8+
9+
#ifdef CONFIG_SHADOW_CALL_STACK
10+
scs_sp .req x18
11+
12+
.macro scs_load tsk, tmp
13+
ldr scs_sp, [\tsk, #TSK_TI_SCS_SP]
14+
.endm
15+
16+
.macro scs_save tsk, tmp
17+
str scs_sp, [\tsk, #TSK_TI_SCS_SP]
18+
.endm
19+
#else
20+
.macro scs_load tsk, tmp
21+
.endm
22+
23+
.macro scs_save tsk, tmp
24+
.endm
25+
#endif /* CONFIG_SHADOW_CALL_STACK */
26+
27+
#endif /* __ASSEMBLY __ */
28+
29+
#endif /* _ASM_SCS_H */

arch/arm64/include/asm/suspend.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#ifndef __ASM_SUSPEND_H
33
#define __ASM_SUSPEND_H
44

5-
#define NR_CTX_REGS 12
5+
#define NR_CTX_REGS 13
66
#define NR_CALLEE_SAVED_REGS 12
77

88
/*

arch/arm64/include/asm/thread_info.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ struct thread_info {
4141
#endif
4242
} preempt;
4343
};
44+
#ifdef CONFIG_SHADOW_CALL_STACK
45+
void *scs_base;
46+
void *scs_sp;
47+
#endif
4448
};
4549

4650
#define thread_saved_pc(tsk) \
@@ -100,11 +104,20 @@ void arch_release_task_struct(struct task_struct *tsk);
100104
_TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
101105
_TIF_SYSCALL_EMU)
102106

107+
#ifdef CONFIG_SHADOW_CALL_STACK
108+
#define INIT_SCS \
109+
.scs_base = init_shadow_call_stack, \
110+
.scs_sp = init_shadow_call_stack,
111+
#else
112+
#define INIT_SCS
113+
#endif
114+
103115
#define INIT_THREAD_INFO(tsk) \
104116
{ \
105117
.flags = _TIF_FOREIGN_FPSTATE, \
106118
.preempt_count = INIT_PREEMPT_COUNT, \
107119
.addr_limit = KERNEL_DS, \
120+
INIT_SCS \
108121
}
109122

110123
#endif /* __ASM_THREAD_INFO_H */

arch/arm64/kernel/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ obj-$(CONFIG_CRASH_CORE) += crash_core.o
6363
obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
6464
obj-$(CONFIG_ARM64_SSBD) += ssbd.o
6565
obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o
66+
obj-$(CONFIG_SHADOW_CALL_STACK) += scs.o
6667

6768
obj-y += vdso/ probes/
6869
obj-$(CONFIG_COMPAT_VDSO) += vdso32/

arch/arm64/kernel/asm-offsets.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ int main(void)
3333
DEFINE(TSK_TI_ADDR_LIMIT, offsetof(struct task_struct, thread_info.addr_limit));
3434
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
3535
DEFINE(TSK_TI_TTBR0, offsetof(struct task_struct, thread_info.ttbr0));
36+
#endif
37+
#ifdef CONFIG_SHADOW_CALL_STACK
38+
DEFINE(TSK_TI_SCS_BASE, offsetof(struct task_struct, thread_info.scs_base));
39+
DEFINE(TSK_TI_SCS_SP, offsetof(struct task_struct, thread_info.scs_sp));
3640
#endif
3741
DEFINE(TSK_STACK, offsetof(struct task_struct, stack));
3842
#ifdef CONFIG_STACKPROTECTOR

0 commit comments

Comments
 (0)