This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] aarch64: fix speculative execution past SVC vulnerability
- From: Anthony Steinhauser <asteinhauser at google dot com>
- To: libc-alpha at sourceware dot org
- Cc: Anthony Steinhauser <asteinhauser at google dot com>
- Date: Tue, 21 Jan 2020 17:29:32 -0800
- Subject: [PATCH] aarch64: fix speculative execution past SVC vulnerability
Even though SVC always causes a jump to another address, aarch64 CPUs
speculatively execute following instructions as if the SVC
instruction was not a jump instruction.
The speculative execution does not cross privilege-levels (to the jump
target as one would expect), but it continues on the kernel privilege
level as if the SVC instruction did not change the control flow -
thus execution anything that is accidentally linked after the SVC
instruction. Later, the results of this speculative execution are
always architecturally discarded, however they can leak data using
microarchitectural side channels. This speculative execution is very
reliable (seems to be unconditional) and it manages to complete even
relatively performance-heavy operations (e.g. multiple dependent
fetches from uncached memory).
Something like:
read(2)
...
[parse read result]
Gets potentially dangerous, since this would allow us potentially
reasonably reliably hit uninitialized memory (with potentially attacker
controlled offsets from prior reads) if we speculate over the SVC in the
syscall. Particularly in a netspectre-like scope.
Bugzilla record:
https://sourceware.org/bugzilla/show_bug.cgi?id=25436
Signed-off-by: Anthony Steinhauser <asteinhauser@google.com>
---
sysdeps/unix/sysv/linux/aarch64/sysdep.h | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
index 00b8e241c8..cf1e6ed45f 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
@@ -147,7 +147,9 @@
# undef DO_CALL
# define DO_CALL(syscall_name, args) \
mov x8, SYS_ify (syscall_name); \
- svc 0
+ svc 0; \
+ dsb nsh; \
+ isb
#else /* not __ASSEMBLER__ */
@@ -191,7 +193,9 @@
{ \
LOAD_ARGS_##nr (args) \
register long _x8 asm ("x8") = (name); \
- asm volatile ("svc 0 // syscall " # name \
+ asm volatile ("svc 0 // syscall\n\t" # name \
+ "dsb nsh\n\t" \
+ "isb" \
: "=r" (_x0) : "r"(_x8) ASM_ARGS_##nr : "memory"); \
_sys_result = _x0; \
} \
--
2.25.0.341.g760bfbb309-goog