s390/entry: add support for syscall stack randomization
authorSven Schnelle <svens@linux.ibm.com>
Thu, 29 Apr 2021 09:14:51 +0000 (11:14 +0200)
committerHeiko Carstens <hca@linux.ibm.com>
Fri, 30 Apr 2021 15:20:39 +0000 (17:20 +0200)
This adds support for adding a random offset to the stack while handling
syscalls. The patch uses get_tod_clock_fast() as this is considered good
enough and has much less performance penalty compared to using
get_random_int(). The patch also adds randomization in pgm_check_handler()
as the sigreturn/rt_sigreturn system calls might be called from there.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Link: https://lore.kernel.org/r/20210429091451.1062594-1-svens@linux.ibm.com
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/Kconfig
arch/s390/include/asm/entry-common.h
arch/s390/kernel/syscall.c
arch/s390/kernel/traps.c

index c1ff874e6c2e63e278dd9a894b70f0f3df1b93ed..1900428ce557c3646df494eb968676792b811042 100644 (file)
@@ -137,6 +137,7 @@ config S390
        select HAVE_ARCH_JUMP_LABEL_RELATIVE
        select HAVE_ARCH_KASAN
        select HAVE_ARCH_KASAN_VMALLOC
+       select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_SOFT_DIRTY
        select HAVE_ARCH_TRACEHOOK
index 9cceb26ed63f2a3d59c51ce22beb2b2ae897f9bd..baa8005090c30914dc2a3c58076bbb58395c81ad 100644 (file)
@@ -4,9 +4,11 @@
 
 #include <linux/sched.h>
 #include <linux/audit.h>
+#include <linux/randomize_kstack.h>
 #include <linux/tracehook.h>
 #include <linux/processor.h>
 #include <linux/uaccess.h>
+#include <asm/timex.h>
 #include <asm/fpu/api.h>
 
 #define ARCH_EXIT_TO_USER_MODE_WORK (_TIF_GUARDED_STORAGE | _TIF_PER_TRAP)
@@ -48,6 +50,14 @@ static __always_inline void arch_exit_to_user_mode(void)
 
 #define arch_exit_to_user_mode arch_exit_to_user_mode
 
+static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
+                                                 unsigned long ti_work)
+{
+       choose_random_kstack_offset(get_tod_clock_fast() & 0xff);
+}
+
+#define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare
+
 static inline bool on_thread_stack(void)
 {
        return !(((unsigned long)(current->stack) ^ current_stack_pointer()) & ~(THREAD_SIZE - 1));
index bc8e650e377d3adb43f672372c1e5936f5f74b8b..4e5cc7d2364e25a9af96b25b923d2bfe0eb130ce 100644 (file)
@@ -142,6 +142,7 @@ void do_syscall(struct pt_regs *regs)
 
 void noinstr __do_syscall(struct pt_regs *regs, int per_trap)
 {
+       add_random_kstack_offset();
        enter_from_user_mode(regs);
 
        memcpy(&regs->gprs[8], S390_lowcore.save_area_sync, 8 * sizeof(unsigned long));
index 63021d4846266d00d5c68e64a956d30f96e6338d..8dd23c703718bacc9bba8d3f397d86cc880a9fc2 100644 (file)
@@ -17,6 +17,7 @@
 #include "asm/ptrace.h"
 #include <linux/kprobes.h>
 #include <linux/kdebug.h>
+#include <linux/randomize_kstack.h>
 #include <linux/extable.h>
 #include <linux/ptrace.h>
 #include <linux/sched.h>
@@ -301,6 +302,7 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
        unsigned int trapnr, syscall_redirect = 0;
        irqentry_state_t state;
 
+       add_random_kstack_offset();
        regs->int_code = *(u32 *)&S390_lowcore.pgm_ilc;
        regs->int_parm_long = S390_lowcore.trans_exc_code;