fix: stacks at top of user VA in own 1 MiB band (guard, heap kept below), 8/16 pages default; kernel fault msg names pid, kind, flags stack overflow; flaky OVERFLOW + spawntest/test-qemu check it

This commit is contained in:
2026-10-28 16:03:06 +01:00
parent 18e8b3ecb8
commit 495bf03484
12 changed files with 93 additions and 22 deletions

View File

@@ -16,6 +16,16 @@ pub mod op {
pub const CRASH: usize = 2;
/// Blocks for good inside the handler.
pub const HANG: usize = 3;
/// Recurses until its stack runs out: the kernel says it overflowed.
pub const OVERFLOW: usize = 4;
}
/// Ever deeper, a KiB of stack a call, until there is none.
#[allow(unconditional_recursion, reason = "running off the stack is what it is for")]
fn deeper(n: usize) -> usize {
let frame = core::hint::black_box([n as u8; 1024]);
// Used after the call, so the call is not a jump.
deeper(n + 1) + frame[n % 1024] as usize
}
/// Everything goes through `handle_call`.
@@ -49,6 +59,9 @@ impl Server for Flaky {
match words[0] {
op::WHO => {}
op::CRASH => panic!("asked to crash"),
op::OVERFLOW => {
core::hint::black_box(deeper(0));
}
op::HANG => {
// A notification nobody signals.
if let Ok(never) = syscall::create_notification() {

View File

@@ -267,6 +267,16 @@ fn restarted_after_hanging() -> Result<(), &'static str> {
Ok(())
}
/// A server that runs off its stack faults on the guard below it, and is
/// restarted like any other that died.
fn restarted_after_overflowing() -> Result<(), &'static str> {
let _ = syscall::request(FLAKY, [flaky::op::OVERFLOW, 0, 0, 0]);
if flaky()? != 1 {
return Err("the overflowed server was not restarted");
}
Ok(())
}
fn check() -> Result<(), &'static str> {
let mut fs = Storage::attach(STORAGE, STORAGE_BUF_VA).map_err(|_| "cannot attach to storage")?;
write_a_file(&mut fs)?;
@@ -305,6 +315,9 @@ fn check() -> Result<(), &'static str> {
restarted_after_hanging()?;
libkos::println!("spawntest: a hung server is noticed, stopped and restarted: ok");
restarted_after_overflowing()?;
libkos::println!("spawntest: a server that overflows its stack is caught and restarted: ok");
Ok(())
}