diff options
author | Andreas Kling <kling@serenityos.org> | 2021-02-14 11:44:21 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-02-14 11:47:14 +0100 |
commit | 41883730206a10fa3043c87135418e829938ad65 (patch) | |
tree | 47d7f55eb146184dcce6b41cd5a22d3e8843254c /Kernel/Syscall.cpp | |
parent | 10b7f6b77eaf4e162f578139b75b1e2302966f49 (diff) | |
download | serenity-41883730206a10fa3043c87135418e829938ad65.zip |
Kernel: Fix TOCTOU in syscall entry region validation
We were doing stack and syscall-origin region validations before
taking the big process lock. There was a window of time where those
regions could then be unmapped/remapped by another thread before we
proceed with our syscall.
This patch closes that window, and makes sys$get_stack_bounds() rely
on the fact that we now know the userspace stack pointer to be valid.
Thanks to @BenWiederhake for spotting this! :^)
Diffstat (limited to 'Kernel/Syscall.cpp')
-rw-r--r-- | Kernel/Syscall.cpp | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 569a6434e9..f087d2a71f 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -169,6 +169,9 @@ void syscall_handler(TrapFrame* trap) PANIC("Syscall from process with IOPL != 0"); } + // NOTE: We take the big process lock before inspecting memory regions. + process.big_lock().lock(); + if (!MM.validate_user_stack(process, VirtualAddress(regs.userspace_esp))) { dbgln("Invalid stack pointer: {:p}", regs.userspace_esp); handle_crash(regs, "Bad stack on syscall entry", SIGSTKFLT); @@ -190,7 +193,6 @@ void syscall_handler(TrapFrame* trap) handle_crash(regs, "Syscall from non-syscall region", SIGSEGV); } - process.big_lock().lock(); u32 function = regs.eax; u32 arg1 = regs.edx; u32 arg2 = regs.ecx; |