From ad579a7eb1c6c386b8f4f0af9d727a05e2592e05 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Sun, 16 Feb 2020 09:33:48 +0000 Subject: Change arm64 system call ABI to skip two instructions. This allows us to insert a barrier after each system call to address a speculative execution issue discovered by Anthony Steinhauser. A change to insert two nop instructions after each system call instruction in crt0.o/libc/ld.so has been committed a few weeks ago, so the transition should go smoothly. However, old static binaries and binaries that roll their own syscalls (like go) will no longer work. Snapshot packages that work with the new syscall ABI are available (including a fixed go). Together with deraadt@ and guenther@ ok deraadt@ --- sys/arch/arm64/arm64/locore.S | 10 +++++----- sys/arch/arm64/arm64/syscall.c | 7 +++++-- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'sys/arch') diff --git a/sys/arch/arm64/arm64/locore.S b/sys/arch/arm64/arm64/locore.S index 849604ece00..f0eff2b4246 100644 --- a/sys/arch/arm64/arm64/locore.S +++ b/sys/arch/arm64/arm64/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.28 2020/02/02 18:55:46 deraadt Exp $ */ +/* $OpenBSD: locore.S,v 1.29 2020/02/16 09:33:47 kettenis Exp $ */ /*- * Copyright (c) 2012-2014 Andrew Turner * All rights reserved. @@ -347,16 +347,16 @@ _C_LABEL(sigcode): 1: mov x8, #SYS_sigreturn svc 0 + dsb nsh + isb .globl _C_LABEL(sigcoderet) _C_LABEL(sigcoderet): - nop - nop /* sigreturn failed, exit */ mov x8, #SYS_exit svc 0 - nop - nop + dsb nsh + isb b 1b END(sigcode) diff --git a/sys/arch/arm64/arm64/syscall.c b/sys/arch/arm64/arm64/syscall.c index 865dd68bbc2..9c530d049bd 100644 --- a/sys/arch/arm64/arm64/syscall.c +++ b/sys/arch/arm64/arm64/syscall.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.c,v 1.4 2020/01/26 01:11:50 kettenis Exp $ */ +/* $OpenBSD: syscall.c,v 1.5 2020/02/16 09:33:47 kettenis Exp $ */ /* * Copyright (c) 2015 Dale Rahn * @@ -50,6 +50,9 @@ svc_handler(trapframe_t *frame) if (__predict_true((frame->tf_spsr & I_bit) == 0)) enable_interrupts(); + /* Skip over barrier. */ + frame->tf_elr += 8; + code = frame->tf_x[8]; ap = &frame->tf_x[0]; @@ -100,7 +103,7 @@ svc_handler(trapframe_t *frame) /* * Reconstruct the pc to point at the svc. */ - frame->tf_elr -= 4; + frame->tf_elr -= 12; break; case EJUSTRETURN: -- cgit v1.2.3