diff options
author | Andreas Kling <kling@serenityos.org> | 2021-01-21 00:06:19 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-01-21 00:14:56 +0100 |
commit | 928ee2c791b0789ad4e845062a8212f50fe299e3 (patch) | |
tree | 8abab1650b870d04b58afe8f3250e4619e563667 /Kernel/Arch | |
parent | 1f53dd0943c02baded5f10cdeb1cd8aea8cf6fa5 (diff) | |
download | serenity-928ee2c791b0789ad4e845062a8212f50fe299e3.zip |
Kernel: Don't let signals unblock threads while handling a page fault
It was possible to signal a process while it was paging in an inode
backed VM object. This would cause the inode read to EINTR, and the
page fault handler would assert.
Solve this by simply not unblocking threads due to signals if they are
currently busy handling a page fault. This is probably not the best way
to solve this issue, so I've added a FIXME to that effect.
Diffstat (limited to 'Kernel/Arch')
-rw-r--r-- | Kernel/Arch/i386/CPU.cpp | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp index e0aa077c3b..20be34443f 100644 --- a/Kernel/Arch/i386/CPU.cpp +++ b/Kernel/Arch/i386/CPU.cpp @@ -25,6 +25,7 @@ */ #include <AK/Assertions.h> +#include <AK/ScopeGuard.h> #include <AK/String.h> #include <AK/StringBuilder.h> #include <AK/Types.h> @@ -257,6 +258,14 @@ void page_fault_handler(TrapFrame* trap) } auto current_thread = Thread::current(); + + if (current_thread) + current_thread->set_handling_page_fault(true); + ScopeGuard guard = [current_thread] { + if (current_thread) + current_thread->set_handling_page_fault(false); + }; + if (!faulted_in_kernel && !MM.validate_user_stack(current_thread->process(), VirtualAddress(regs.userspace_esp))) { dbgln("Invalid stack pointer: {}", VirtualAddress(regs.userspace_esp)); handle_crash(regs, "Bad stack on page fault", SIGSTKFLT); |