summaryrefslogtreecommitdiffstats
path: root/rsdos
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-02 23:28:29 +0200
committersalmonik <salmonik@tuta.io>2026-08-02 23:28:29 +0200
commitf846a9551bf30d61026fa9c9ccea78479ced321b (patch)
tree10158ca300cc51f44fc9afee9c2b3092554d880b /rsdos
parentv0.5.7: guard reports the drop's size/align — identifies the clobbered struct (diff)
downloadrs-dos-f846a9551bf30d61026fa9c9ccea78479ced321b.tar.gz
rs-dos-f846a9551bf30d61026fa9c9ccea78479ced321b.zip
v0.5.7: drop test-poison hooks; vt heap-struct verify at shell entry
The OptiPlex's first banner write #GPs when the vt cells VecData holds firmware 0xAA fill instead of a real buffer pointer. The poison/fill test hooks (stack + free-heap + free-page 0x00AAAAAA) were removed from the release image — they changed boot behavior and may walk a corrupt free list over live blocks. Added vt::debug_verify() (cells/rendered ptr/cap/len + in-heap check) at shell entry: the next real-hardware boot shows whether the corruption is present at shell entry or lands during the banner write.
Diffstat (limited to 'rsdos')
-rw-r--r--rsdos/src/main.rs40
1 files changed, 7 insertions, 33 deletions
diff --git a/rsdos/src/main.rs b/rsdos/src/main.rs
index 52b37ec..42f95e5 100644
--- a/rsdos/src/main.rs
+++ b/rsdos/src/main.rs
@@ -344,22 +344,13 @@ pub unsafe extern "efiapi" fn efi_main(image_handle: Handle, system_table: *mut
344 } else { 344 } else {
345 rsnix::serial_println!("cursor: no mouse — overlay disabled"); 345 rsnix::serial_println!("cursor: no mouse — overlay disabled");
346 } 346 }
347 // TEST HOOK: reproduce the OptiPlex '0xaaaaaa' uninit-drop crash in 347 // Shell-entry self-check: verify the vt grid structs are sane right
348 // QEMU. The real hardware's stack carries 0xAA fill left by 348 // before the shell's first print. The OptiPlex crashes in the first
349 // firmware; any shell value that is dropped without being written 349 // banner write when the cells VecData (or the shadow) holds the
350 // then frees garbage and trips the dealloc guard. Filling the 350 // firmware's 0xAA fill instead of real values — this line shows
351 // shell's future stack region with 0xAA here makes the same bug 351 // whether the corruption is already present at shell entry or lands
352 // visible on QEMU (serial + gdb available) instead of only on the 352 // later, and prints the exact field values when it is.
353 // OptiPlex. 353 rsnix::vt::debug_verify();
354 stack_fill_aa();
355 // Poison the free heap AND the free pages with the OptiPlex's
356 // 0x00AAAAAA scrub pattern — the firmware's leftover fills both the
357 // heap (freed pool) and the pages the allocators hand out (heap
358 // growth, task stacks). Together with the stack fill this makes
359 // any uninitialized read reproduce the real machine's crashes in
360 // QEMU (garbage sizes → alloc panics, garbage ptrs → dealloc guard).
361 rsnix::memory::poison_free_blocks_aa();
362 rsnix::memory::poison_free_pages_aa();
363 shell::run(); 354 shell::run();
364} 355}
365 356
@@ -368,23 +359,6 @@ pub unsafe extern "efiapi" fn efi_main(image_handle: Handle, system_table: *mut
368/// headroom. 128 KiB covers the whole shell frame chain on QEMU and 359/// headroom. 128 KiB covers the whole shell frame chain on QEMU and
369/// the OptiPlex. Best-effort: the region is below rsp inside the boot 360/// the OptiPlex. Best-effort: the region is below rsp inside the boot
370/// stack mapping; the call into `shell::run` overwrites the top word. 361/// stack mapping; the call into `shell::run` overwrites the top word.
371fn stack_fill_aa() {
372 let rsp: usize;
373 unsafe {
374 core::arch::asm!("mov {}, rsp", out(reg) rsp);
375 }
376 let top = rsp - 0x100;
377 let bottom = rsp - 0x21100;
378 unsafe {
379 let mut p = bottom;
380 while p < top {
381 core::ptr::write_volatile(p as *mut u64, 0x00AAAAAA00AAAAAA);
382 p += 8;
383 }
384 }
385 rsnix::serial_println!("stack: 0x00AAAAAA-fill 0x{:x}..0x{:x}", bottom, top);
386}
387
388// --------------------------------------------------------------------------- 362// ---------------------------------------------------------------------------
389// Print a memory summary from the stashed memory map 363// Print a memory summary from the stashed memory map
390// --------------------------------------------------------------------------- 364// ---------------------------------------------------------------------------