From 1d94b5eb040d052ba96ac3e0c08b54b5f3ed84e1 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 1 Jan 2020 23:10:25 +0100 Subject: [PATCH] Kernel: Add a random offset to kernel stacks upon syscall entry When entering the kernel from a syscall, we now insert a small bit of stack padding after the RegisterDump. This makes kernel stacks less deterministic across syscalls and may make some bugs harder to exploit. Inspired by Elena Reshetova's talk on kernel stack exploitation. --- Kernel/Arch/i386/CPU.h | 8 ++++++++ Kernel/Syscall.cpp | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/Kernel/Arch/i386/CPU.h b/Kernel/Arch/i386/CPU.h index c1980f0da41..482247a2d26 100644 --- a/Kernel/Arch/i386/CPU.h +++ b/Kernel/Arch/i386/CPU.h @@ -447,6 +447,14 @@ inline void read_tsc(u32& lsw, u32& msw) : "=d"(msw), "=a"(lsw)); } +inline u64 read_tsc() +{ + u32 lsw; + u32 msw; + read_tsc(lsw, msw); + return ((u64)msw << 32) | lsw; +} + struct Stopwatch { union SplitQword { struct { diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index b9e0391e35d..98cecb53435 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -92,6 +92,12 @@ int handle(RegisterDump& regs, u32 function, u32 arg1, u32 arg2, u32 arg3) void syscall_handler(RegisterDump regs) { + // Apply a random offset in the range 0-255 to the stack pointer, + // to make kernel stacks a bit less deterministic. + auto* ptr = (char*)__builtin_alloca(read_tsc() & 0xff); + asm volatile("" + : "=m"(*ptr)); + auto& process = current->process(); if (!MM.validate_user_stack(process, VirtualAddress(regs.esp_if_crossRing))) {