Kernel: Fix stack OOB detection

I now check both interrupt and normal stack to detect OOB. Processes
are killed if they encouner stack over/under flow.
This commit is contained in:
Bananymous 2023-10-30 12:17:08 +02:00
parent b5d873dfae
commit 130a69bac6
2 changed files with 15 additions and 8 deletions

View File

@ -181,14 +181,20 @@ namespace Kernel::IDT
{ {
// Check if stack is OOB // Check if stack is OOB
auto& stack = Thread::current().stack(); auto& stack = Thread::current().stack();
if (interrupt_stack.rsp < stack.vaddr()) auto& istack = Thread::current().interrupt_stack();
if (stack.vaddr() < interrupt_stack.rsp && interrupt_stack.rsp <= stack.vaddr() + stack.size())
; // using normal stack
else if (istack.vaddr() < interrupt_stack.rsp && interrupt_stack.rsp <= istack.vaddr() + istack.size())
; // using interrupt stack
else
{ {
derrorln("Stack overflow"); derrorln("Stack pointer out of bounds!");
goto done; derrorln("rsp {H}, stack {H}->{H}, istack {H}->{H}",
} interrupt_stack.rsp,
if (interrupt_stack.rsp >= stack.vaddr() + stack.size()) stack.vaddr(), stack.vaddr() + stack.size(),
{ istack.vaddr(), istack.vaddr() + istack.size()
derrorln("Stack underflow"); );
Thread::current().handle_signal(SIGKILL);
goto done; goto done;
} }
@ -207,7 +213,7 @@ namespace Kernel::IDT
if (result.is_error()) if (result.is_error())
{ {
dwarnln("Demand paging: {}", result.error()); dwarnln("Demand paging: {}", result.error());
Thread::current().handle_signal(SIGTERM); Thread::current().handle_signal(SIGKILL);
goto done; goto done;
} }
} }

View File

@ -71,6 +71,7 @@ namespace Kernel
vaddr_t stack_base() const { return m_stack->vaddr(); } vaddr_t stack_base() const { return m_stack->vaddr(); }
size_t stack_size() const { return m_stack->size(); } size_t stack_size() const { return m_stack->size(); }
VirtualRange& stack() { return *m_stack; } VirtualRange& stack() { return *m_stack; }
VirtualRange& interrupt_stack() { return *m_interrupt_stack; }
vaddr_t interrupt_stack_base() const { return m_interrupt_stack ? m_interrupt_stack->vaddr() : 0; } vaddr_t interrupt_stack_base() const { return m_interrupt_stack ? m_interrupt_stack->vaddr() : 0; }
size_t interrupt_stack_size() const { return m_interrupt_stack ? m_interrupt_stack->size() : 0; } size_t interrupt_stack_size() const { return m_interrupt_stack ? m_interrupt_stack->size() : 0; }