Kernel: Don't crash in page_fault_handler if current_thread is null

If we are attempting to emit debugging information about an unhandleable
page fault, don't crash trying to kill threads or dump processes if the
current_thread isn't set in TLS. Attempt to keep proceeding in order to
dump as much useful information as possible.

Related: #6948
This commit is contained in:
Brian Gianforcaro 2021-05-14 22:33:18 -07:00 committed by Andreas Kling
parent 00498e0405
commit db78331741
Notes: sideshowbarker 2024-07-18 18:07:43 +09:00

View file

@ -276,7 +276,7 @@ void page_fault_handler(TrapFrame* trap)
return;
}
if (response != PageFaultResponse::OutOfMemory) {
if (response != PageFaultResponse::OutOfMemory && current_thread) {
if (current_thread->has_signal_handler(SIGSEGV)) {
current_thread->send_urgent_signal_to_self(SIGSEGV);
return;
@ -310,16 +310,18 @@ void page_fault_handler(TrapFrame* trap)
dbgln("Note: Address {} looks like a possible nullptr dereference", VirtualAddress(fault_address));
}
auto& current_process = current_thread->process();
if (current_process.is_user_process()) {
current_process.set_coredump_metadata("fault_address", String::formatted("{:p}", fault_address));
current_process.set_coredump_metadata("fault_type", fault.type() == PageFault::Type::PageNotPresent ? "NotPresent" : "ProtectionViolation");
String fault_access;
if (fault.is_instruction_fetch())
fault_access = "Execute";
else
fault_access = fault.access() == PageFault::Access::Read ? "Read" : "Write";
current_process.set_coredump_metadata("fault_access", fault_access);
if (current_thread) {
auto& current_process = current_thread->process();
if (current_process.is_user_process()) {
current_process.set_coredump_metadata("fault_address", String::formatted("{:p}", fault_address));
current_process.set_coredump_metadata("fault_type", fault.type() == PageFault::Type::PageNotPresent ? "NotPresent" : "ProtectionViolation");
String fault_access;
if (fault.is_instruction_fetch())
fault_access = "Execute";
else
fault_access = fault.access() == PageFault::Access::Read ? "Read" : "Write";
current_process.set_coredump_metadata("fault_access", fault_access);
}
}
handle_crash(regs, "Page Fault", SIGSEGV, response == PageFaultResponse::OutOfMemory);