Kernel: Fix stack pointer OOB check

i686 does not push the stack pointer on interrupt when no CPL change
happens.
This commit is contained in:
Bananymous 2024-07-22 00:27:08 +03:00
parent 1ee37cb671
commit 9f90eeab05
1 changed files with 21 additions and 23 deletions

View File

@ -173,15 +173,17 @@ namespace Kernel
if (tid) if (tid)
{ {
auto& thread = Thread::current();
#if __enable_sse #if __enable_sse
Thread::current().save_sse(); thread.save_sse();
#endif #endif
if (isr == ISR::PageFault) if (isr == ISR::PageFault && Thread::current().is_userspace())
{ {
// Check if stack is OOB // Check if stack is OOB
auto& thread = Thread::current(); if (ARCH(i686) && !GDT::is_user_segment(interrupt_stack->cs))
if (thread.userspace_stack_bottom() < interrupt_stack->sp && interrupt_stack->sp <= thread.userspace_stack_top()) ; // 32 bit does not push stack pointer when no CPL change happens
else if (thread.userspace_stack_bottom() < interrupt_stack->sp && interrupt_stack->sp <= thread.userspace_stack_top())
; // using userspace stack ; // using userspace stack
else if (thread.kernel_stack_bottom() < interrupt_stack->sp && interrupt_stack->sp <= thread.kernel_stack_top()) else if (thread.kernel_stack_bottom() < interrupt_stack->sp && interrupt_stack->sp <= thread.kernel_stack_top())
; // using kernel stack ; // using kernel stack
@ -198,27 +200,23 @@ namespace Kernel
goto done; goto done;
} }
// Demand paging is only supported in userspace // Try demand paging on non present pages
if (thread.is_userspace()) PageFaultError page_fault_error;
page_fault_error.raw = error;
if (pid && !page_fault_error.present)
{ {
// Try demand paging on non present pages Processor::set_interrupt_state(InterruptState::Enabled);
PageFaultError page_fault_error; auto result = Process::current().allocate_page_for_demand_paging(regs->cr2);
page_fault_error.raw = error; Processor::set_interrupt_state(InterruptState::Disabled);
if (!page_fault_error.present)
if (!result.is_error() && result.value())
goto done;
if (result.is_error())
{ {
Processor::set_interrupt_state(InterruptState::Enabled); dwarnln("Demand paging: {}", result.error());
auto result = Process::current().allocate_page_for_demand_paging(regs->cr2); Thread::current().handle_signal(SIGKILL);
Processor::set_interrupt_state(InterruptState::Disabled); goto done;
if (!result.is_error() && result.value())
goto done;
if (result.is_error())
{
dwarnln("Demand paging: {}", result.error());
Thread::current().handle_signal(SIGKILL);
goto done;
}
} }
} }
} }