#![no_main] //! Console-command extraction decodes every function in the image and does arithmetic on values the //! FILE controls at every step: `lea` displacements are added to tracked register contents, member //! offsets are added to a symbolic base, and the accessor window walks `arg3 + k*8` looking for a stored //! pointer. A crafted (or truncated) `.so` can make any of those wrap, point outside every section, or //! nest arbitrarily deep — and the reader must answer with fewer commands, never a panic. //! //! It also exercises the two indirections that resolve a callback (a static object's first virtual, and //! a constructor-stored member) against pointers the file chose, which is the same untrusted-chase shape //! the Valve table readers had to be hardened for. use libfuzzer_sys::fuzz_target; use source2rosetta::concmd; use source2rosetta::elf::CodeImage; fuzz_target!(|data: &[u8]| { let Ok(img) = CodeImage::from_bytes(data.to_vec()) else { return; }; let cmds = concmd::console_commands(&img); for c in &cmds { // A recovered handler is only ever accepted because it lands in executable code, so the reader // must never hand back one that does not — a caller treats this as a locator. assert!( img.is_code(c.handler), "a non-executable handler was recorded for {:?}", c.name ); // The name gate is what stops prose and format strings being read as commands. assert!( !c.name.is_empty() && c.name.len() <= 64, "an implausible command name was recorded: {:?}", c.name ); // Flag decoding is a pure bit test and must stay within the bits it claims to know. let named = concmd::flag_names(c.flags); assert!(named.len() <= 12, "more flag names than there are flag bits"); let _ = (c.description.len(), c.form.describe(), c.flags); } // Commands are deduped on (name, address), so no pair may survive twice. let mut seen: Vec<(&str, u64)> = cmds.iter().map(|c| (c.name.as_str(), c.handler)).collect(); let before = seen.len(); seen.sort_unstable(); seen.dedup(); assert_eq!(before, seen.len(), "a duplicate (name, handler) survived"); });