From 3f08ca44efe7aa4bb49a171decf0cabf59e922d3 Mon Sep 17 00:00:00 2001 From: "Celian G." Date: Thu, 7 May 2026 17:13:32 +0200 Subject: [PATCH] Fix panic on snapshot restore of stack guard pages Edit snapshot.rs to restore stack guard pages (with no read / write permissions) instead of panicking. --- crates/libafl_qemu/src/modules/usermode/snapshot.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/libafl_qemu/src/modules/usermode/snapshot.rs b/crates/libafl_qemu/src/modules/usermode/snapshot.rs index 50c26f59166..ddf8b1b498d 100644 --- a/crates/libafl_qemu/src/modules/usermode/snapshot.rs +++ b/crates/libafl_qemu/src/modules/usermode/snapshot.rs @@ -493,7 +493,14 @@ impl SnapshotModule { unsafe { qemu.write_mem_unchecked(*page, &data[..]) }; } else { - panic!("Cannot restored a dirty but unsaved page"); + // Page was non-readable at snapshot time (e.g. a PROT_NONE guard + // page for a thread stack that glibc created before the snapshot). + // We have no saved content; zero it so subsequent runs see a clean + // state, then reset_maps will re-apply the original permissions. + if !Self::modify_mapping(qemu, new_maps, *page) { + return true; // Restore later + } + unsafe { qemu.write_mem_unchecked(*page, &SNAPSHOT_PAGE_ZEROES) }; } } false @@ -531,7 +538,8 @@ impl SnapshotModule { if let Some(data) = info.data.as_ref() { unsafe { qemu.write_mem_unchecked(*page, &data[..]) }; } else { - panic!("Cannot restored a dirty but unsaved page"); + // Non-readable at snapshot time; zero it. + unsafe { qemu.write_mem_unchecked(*page, &SNAPSHOT_PAGE_ZEROES) }; } } }