Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 332eaac7 authored by Sami Tolvanen's avatar Sami Tolvanen Committed by Alistair Delva
Browse files

FROMLIST: arm64: implement Shadow Call Stack

This change implements shadow stack switching, initial SCS set-up,
and interrupt shadow stacks for arm64.

Bug: 145210207
Change-Id: I3d5b9ec374418b110d1f351e1abd41610cfee597
(am from https://lore.kernel.org/patchwork/patch/1149062/

)
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarSami Tolvanen <samitolvanen@google.com>
parent fb3573ae
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ config ARM64
	select ARCH_SUPPORTS_MEMORY_FAILURE
	select ARCH_SUPPORTS_LTO_CLANG
	select ARCH_SUPPORTS_THINLTO
	select ARCH_SUPPORTS_SHADOW_CALL_STACK if CC_HAVE_SHADOW_CALL_STACK
	select ARCH_SUPPORTS_ATOMIC_RMW
	select ARCH_SUPPORTS_INT128 if GCC_VERSION >= 50000 || CC_IS_CLANG
	select ARCH_SUPPORTS_NUMA_BALANCING
@@ -824,6 +825,11 @@ config ARCH_WANT_HUGE_PMD_SHARE
config ARCH_HAS_CACHE_LINE_SIZE
	def_bool y


# Supported by clang >= 7.0
config CC_HAVE_SHADOW_CALL_STACK
	def_bool $(cc-option, -fsanitize=shadow-call-stack -ffixed-x18)

config SECCOMP
	bool "Enable seccomp to safely compute untrusted bytecode"
	---help---
+37 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_SCS_H
#define _ASM_SCS_H

#ifndef __ASSEMBLY__

#include <linux/scs.h>

#ifdef CONFIG_SHADOW_CALL_STACK

extern void scs_init_irq(void);

static __always_inline void scs_save(struct task_struct *tsk)
{
	void *s;

	asm volatile("mov %0, x18" : "=r" (s));
	task_set_scs(tsk, s);
}

static inline void scs_overflow_check(struct task_struct *tsk)
{
	if (unlikely(scs_corrupted(tsk)))
		panic("corrupted shadow stack detected inside scheduler\n");
}

#else /* CONFIG_SHADOW_CALL_STACK */

static inline void scs_init_irq(void) {}
static inline void scs_save(struct task_struct *tsk) {}
static inline void scs_overflow_check(struct task_struct *tsk) {}

#endif /* CONFIG_SHADOW_CALL_STACK */

#endif /* __ASSEMBLY __ */

#endif /* _ASM_SCS_H */
+4 −0
Original line number Diff line number Diff line
@@ -54,6 +54,10 @@ extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk);

DECLARE_PER_CPU(unsigned long *, irq_stack_ptr);

#ifdef CONFIG_SHADOW_CALL_STACK
DECLARE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr);
#endif

static inline bool on_irq_stack(unsigned long sp,
				struct stack_info *info)
{
+3 −0
Original line number Diff line number Diff line
@@ -43,6 +43,9 @@ struct thread_info {
	u64			ttbr0;		/* saved TTBR0_EL1 */
#endif
	int			preempt_count;	/* 0 => preemptable, <0 => bug */
#ifdef CONFIG_SHADOW_CALL_STACK
	void			*shadow_call_stack;
#endif
};

#define thread_saved_pc(tsk)	\
+1 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
arm64-obj-$(CONFIG_CRASH_CORE)		+= crash_core.o
arm64-obj-$(CONFIG_ARM_SDE_INTERFACE)	+= sdei.o
arm64-obj-$(CONFIG_ARM64_SSBD)		+= ssbd.o
arm64-obj-$(CONFIG_SHADOW_CALL_STACK)	+= scs.o

obj-y					+= $(arm64-obj-y) vdso/ probes/
obj-m					+= $(arm64-obj-m)
Loading