mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:17:45 +00:00
Kernel: Implement some basic stack pointer validation
VM regions can now be marked as stack regions, which is then validated on syscall, and on page fault. If a thread is caught with its stack pointer pointing into anything that's *not* a Region with its stack bit set, we'll crash the whole process with SIGSTKFLT. Userspace must now allocate custom stacks by using mmap() with the new MAP_STACK flag. This mechanism was first introduced in OpenBSD, and now we have it too, yay! :^)
This commit is contained in:
parent
197ed1bb2a
commit
794758df3a
12 changed files with 101 additions and 5 deletions
|
@ -131,7 +131,7 @@ static void dump(const RegisterDump& regs)
|
|||
u16 ss;
|
||||
u32 esp;
|
||||
if (!current || current->process().is_ring0()) {
|
||||
ss = regs.ds;
|
||||
ss = regs.ss;
|
||||
esp = regs.esp;
|
||||
} else {
|
||||
ss = regs.ss_if_crossRing;
|
||||
|
@ -160,14 +160,14 @@ static void dump(const RegisterDump& regs)
|
|||
}
|
||||
}
|
||||
|
||||
static void handle_crash(RegisterDump& regs, const char* description, int signal)
|
||||
void handle_crash(RegisterDump& regs, const char* description, int signal)
|
||||
{
|
||||
if (!current) {
|
||||
kprintf("%s with !current\n", description);
|
||||
hang();
|
||||
}
|
||||
|
||||
kprintf("\033[31;1mCRASH: %s %s: %s(%u)\033[0m\n",
|
||||
kprintf("\033[31;1mCRASH: %s. %s: %s(%u)\033[0m\n",
|
||||
description,
|
||||
current->process().is_ring0() ? "Kernel" : "Process",
|
||||
current->process().name().characters(),
|
||||
|
@ -181,6 +181,7 @@ static void handle_crash(RegisterDump& regs, const char* description, int signal
|
|||
hang();
|
||||
}
|
||||
|
||||
cli();
|
||||
current->process().crash(signal, regs.eip);
|
||||
}
|
||||
|
||||
|
@ -263,6 +264,13 @@ void exception_14_handler(RegisterDump regs)
|
|||
dump(regs);
|
||||
#endif
|
||||
|
||||
bool faulted_in_userspace = (regs.cs & 3) == 3;
|
||||
if (faulted_in_userspace && !MM.validate_user_stack(current->process(), VirtualAddress(regs.esp_if_crossRing))) {
|
||||
dbgprintf("Invalid stack pointer: %p\n", regs.esp_if_crossRing);
|
||||
handle_crash(regs, "Bad stack on page fault", SIGSTKFLT);
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
auto response = MM.handle_page_fault(PageFault(regs.exception_code, VirtualAddress(fault_address)));
|
||||
|
||||
if (response == PageFaultResponse::ShouldCrash) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue