diff options
| author | salmonik <salmonik@tuta.io> | 2026-08-02 21:47:18 +0200 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-08-02 21:47:18 +0200 |
| commit | 0187b802113a10a9ee99af48b811cd332c660a13 (patch) | |
| tree | b0873f7b2dcf6be1c575c8fe1919a72f041bba49 /rsnix/src/sched.rs | |
| parent | v0.5.6: fault dumps carry kernel image base + stack backtrace (diff) | |
| download | rs-dos-0187b802113a10a9ee99af48b811cd332c660a13.tar.gz rs-dos-0187b802113a10a9ee99af48b811cd332c660a13.zip | |
v0.5.7: allocator corruption guard + full register dump for real-hardware repro
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.
Diffstat (limited to '')
| -rw-r--r-- | rsnix/src/sched.rs | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/rsnix/src/sched.rs b/rsnix/src/sched.rs index a31ea6e..dd1409e 100644 --- a/rsnix/src/sched.rs +++ b/rsnix/src/sched.rs | |||
| @@ -730,7 +730,49 @@ pub(crate) fn fault_dump(kind: &str, cr2: u64, frame: &crate::interrupts::IntFra | |||
| 730 | let l2 = core::str::from_utf8(&b2[..n2]).unwrap_or(""); | 730 | let l2 = core::str::from_utf8(&b2[..n2]).unwrap_or(""); |
| 731 | let l3 = core::str::from_utf8(&b3[..n3]).unwrap_or(""); | 731 | let l3 = core::str::from_utf8(&b3[..n3]).unwrap_or(""); |
| 732 | let l4 = core::str::from_utf8(&b4[..n4]).unwrap_or("bt=?"); | 732 | let l4 = core::str::from_utf8(&b4[..n4]).unwrap_or("bt=?"); |
| 733 | let lines = [l1, l2, l3, l4]; | 733 | |
| 734 | // Register dump — the faulting register state, so a real-hardware | ||
| 735 | // repro can be diagnosed without serial. Two lines on screen (the | ||
| 736 | // band is clamped), full set in crash.log via `lines`. | ||
| 737 | let mut r1 = [0u8; 160]; | ||
| 738 | let rn1 = { | ||
| 739 | let mut w = crate::strbuf::FmtBuf::new(&mut r1); | ||
| 740 | let _ = fmt::write( | ||
| 741 | &mut w, | ||
| 742 | core::format_args!( | ||
| 743 | "rax={:#x} rcx={:#x} rdx={:#x} rsi={:#x} rdi={:#x}", | ||
| 744 | frame.rax, frame.rcx, frame.rdx, frame.rsi, frame.rdi | ||
| 745 | ), | ||
| 746 | ); | ||
| 747 | w.len() | ||
| 748 | }; | ||
| 749 | let mut r2 = [0u8; 160]; | ||
| 750 | let rn2 = { | ||
| 751 | let mut w = crate::strbuf::FmtBuf::new(&mut r2); | ||
| 752 | let _ = fmt::write( | ||
| 753 | &mut w, | ||
| 754 | core::format_args!( | ||
| 755 | "rbx={:#x} r8={:#x} r9={:#x} r10={:#x} r11={:#x} r12={:#x} r13={:#x} r14={:#x} r15={:#x}", | ||
| 756 | frame.rbx, | ||
| 757 | frame.r8, | ||
| 758 | frame.r9, | ||
| 759 | frame.r10, | ||
| 760 | frame.r11, | ||
| 761 | frame.r12, | ||
| 762 | frame.r13, | ||
| 763 | frame.r14, | ||
| 764 | frame.r15 | ||
| 765 | ), | ||
| 766 | ); | ||
| 767 | w.len() | ||
| 768 | }; | ||
| 769 | let l5 = core::str::from_utf8(&r1[..rn1]).unwrap_or(""); | ||
| 770 | let l6 = core::str::from_utf8(&r2[..rn2]).unwrap_or(""); | ||
| 771 | crate::serial::write_raw(l5); | ||
| 772 | crate::serial::write_raw("\r\n"); | ||
| 773 | crate::serial::write_raw(l6); | ||
| 774 | crate::serial::write_raw("\r\n"); | ||
| 775 | let lines = [l1, l2, l3, l4, l5, l6]; | ||
| 734 | crate::gop::dump_lines(&lines); | 776 | crate::gop::dump_lines(&lines); |
| 735 | 777 | ||
| 736 | // Best-effort: persist the report to the disk so it survives the | 778 | // Best-effort: persist the report to the disk so it survives the |
