From 0187b802113a10a9ee99af48b811cd332c660a13 Mon Sep 17 00:00:00 2001 From: salmonik Date: Sun, 2 Aug 2026 21:47:18 +0200 Subject: v0.5.7: allocator corruption guard + full register dump for real-hardware repro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The OptiPlex #GP (vec=13 in __rust_dealloc) frees a garbage pointer: the back-pointer at [ptr-8] is clobbered by the time the shell drops its Parsed struct. A blind store to the bogus block header was an opaque #GP — now it is a readable report: - dealloc validates the back-pointer (in-heap block, sane size, in-use) before trusting it; on failure it prints ptr/block/heap range, the memory around the block header, and the live stack chain, writes the crash band + crash.log, and halts (memory.rs: heap_guard_report). - fault dumps now carry the full register set (rax..rdi, rbx, r8..r15) so the next repro shows the exact freed ptr and clobbered value. - new 'corrupt' shell hook deliberately clobbers a live block's back-pointer to prove the guard fires (test-fault-style halt). Verified: test-msg/test-disk/test-fault pass; corrupt hook reports ptr=.. block=0xdeedbeef... with mem dump instead of #GP. rs-dos.img rebuilt with the release kernel. --- shell/src/lib.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'shell') diff --git a/shell/src/lib.rs b/shell/src/lib.rs index a32d259..175a2c7 100644 --- a/shell/src/lib.rs +++ b/shell/src/lib.rs @@ -740,6 +740,7 @@ write `{} TIL `", "kill" => cmd_kill(&parsed), "demo" => cmd_demo(&parsed), "fault" => cmd_fault(), + "corrupt" => cmd_corrupt(), "crashlog" => cmd_crashlog(), "stall" => cmd_stall(&parsed), _ => term_err(&alloc::format!("unknown command: {}", cmd)), @@ -839,6 +840,21 @@ fn cmd_fault() { } } +/// Deliberately clobber a live heap block's back-pointer, then free it — +/// test hook that proves the allocator's corruption guard fires with a +/// readable report (instead of a #GP inside `__rust_dealloc`). The +/// system stops; the log must show `!!! heap corruption in dealloc`. +fn cmd_corrupt() { + term_println("corrupt: clobbering a live block's back-pointer..."); + let s = String::from("hello heap guard"); + let ptr = s.as_ptr() as usize; + unsafe { + *((ptr - 8) as *mut usize) = 0xdeed_beef_deed_beefusize; + } + drop(s); + term_println("corrupt: guard did NOT fire (unexpected)"); +} + /// Debug hook: run the crash-log FAT write from the *shell* context (not /// the fault ISR) to compare behaviour. fn cmd_crashlog() { -- cgit v1.2.3