diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-09-05 11:18:38 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-09-05 11:21:18 +0200 |
| commit | 3eb72bb6bc7446df3e34bd990cb84a0b8178b9cd (patch) | |
| tree | 21a8c11f4d140c5babe921efa2b9acfb125df1b3 /arch/x86_64 | |
| parent | 3697f01a3906815cbbbe8927f50045163976c1db (diff) | |
| download | kernel-3eb72bb6bc7446df3e34bd990cb84a0b8178b9cd.tar.xz kernel-3eb72bb6bc7446df3e34bd990cb84a0b8178b9cd.zip | |
x86_64/cpu: improve stack overflow detection
Diffstat (limited to 'arch/x86_64')
| -rw-r--r-- | arch/x86_64/arch/cpu/interrupts.cpp | 29 | ||||
| -rw-r--r-- | arch/x86_64/scripts/kernel.ld | 2 |
2 files changed, 29 insertions, 2 deletions
diff --git a/arch/x86_64/arch/cpu/interrupts.cpp b/arch/x86_64/arch/cpu/interrupts.cpp index 94806621..f27c3a2e 100644 --- a/arch/x86_64/arch/cpu/interrupts.cpp +++ b/arch/x86_64/arch/cpu/interrupts.cpp @@ -9,7 +9,9 @@ #include <kapi/system.hpp> #include <kstd/print.hpp> +#include <kstd/units.hpp> +#include <cstddef> #include <cstdint> namespace arch::cpu @@ -17,6 +19,9 @@ namespace arch::cpu namespace { + extern "C" std::byte __kernel_stack_bottom[]; // NOLINT(readability-identifier-naming) + extern "C" std::byte __ist1_stack_bottom[]; // NOLINT(readability-identifier-naming) + enum struct exception { divide_error, @@ -128,8 +133,28 @@ namespace arch::cpu auto handle_double_fault(interrupt_frame * frame) -> void { - kapi::system::panic("[ARCH:CPU] Double fault! Possible kernel stack corruption! rsp was {}", - frame->cpu_saved.rsp); + auto const rsp = frame->cpu_saved.rsp; + auto const rip = frame->cpu_saved.rip; + auto const kernel_stack_bottom = kapi::memory::linear_address{__kernel_stack_bottom}; + auto const ist1_stack_bottom = kapi::memory::linear_address{__ist1_stack_bottom}; + + auto const overflowed_kernel = rsp < kernel_stack_bottom && rsp >= kernel_stack_bottom - kapi::memory::page::size; + auto const overflowed_ist1 = rsp < ist1_stack_bottom && rsp >= ist1_stack_bottom - kapi::memory::page::size; + + if (overflowed_kernel || overflowed_ist1) + { + auto const overflowed_what = overflowed_kernel ? "kernel" : "ist1"; + auto const overflowed_by = + kstd::bytes{static_cast<std::size_t>((overflowed_kernel ? kernel_stack_bottom : ist1_stack_bottom) - rsp)}; + + kapi::system::panic("[ARCH:CPU] Suspected {} stack overflow: \n" // + "\toverflowed by: {:#}\n" // + "\trsp: {}\n" // + "\trip: {}\n", // + overflowed_what, overflowed_by, rsp, rip); + } + + kapi::system::panic("[ARCH:CPU] Double fault at {}", rip); } } // namespace diff --git a/arch/x86_64/scripts/kernel.ld b/arch/x86_64/scripts/kernel.ld index 8cd6c1c3..f96152d7 100644 --- a/arch/x86_64/scripts/kernel.ld +++ b/arch/x86_64/scripts/kernel.ld @@ -100,6 +100,7 @@ SECTIONS .kernel_stack ALIGN(4K) : AT (ADDR (.kernel_stack) - TEACHOS_VMA) { + PROVIDE_HIDDEN(__kernel_stack_bottom = .); *(.stack) } :kernel_data @@ -107,6 +108,7 @@ SECTIONS .kernel_ist1_stack ALIGN(4K) : AT (ADDR (.kernel_ist1_stack) - TEACHOS_VMA) { + PROVIDE_HIDDEN(__ist1_stack_bottom = .); *(.ist1_stack) } :kernel_data |
