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:
parent
1ee37cb671
commit
9f90eeab05
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue