Skip to content

Commit d7eb3bd

Browse files
LibAFL_QEMU: Fix snapshots for large mappings (#3252)
1 parent e832e32 commit d7eb3bd

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

libafl_qemu/src/modules/usermode/snapshot.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -302,13 +302,12 @@ impl SnapshotModule {
302302
}
303303

304304
pub fn access(&mut self, addr: GuestAddr, size: usize) {
305-
// ASSUMPTION: the access can only cross 2 pages
306-
debug_assert!(size <= SNAPSHOT_PAGE_SIZE);
307-
let page = addr & SNAPSHOT_PAGE_MASK;
308-
self.page_access(page);
309-
let second_page = (addr + size as GuestAddr - 1) & SNAPSHOT_PAGE_MASK;
310-
if page != second_page {
311-
self.page_access(second_page);
305+
let start = addr & SNAPSHOT_PAGE_MASK;
306+
let end = (addr + size as GuestAddr - 1) & SNAPSHOT_PAGE_MASK;
307+
/* Apparently there is a performance hit to using an inclusive range */
308+
#[allow(clippy::range_plus_one)]
309+
for page in (start..end + 1).step_by(SNAPSHOT_PAGE_SIZE) {
310+
self.page_access(page);
312311
}
313312
}
314313

@@ -920,7 +919,13 @@ where
920919
match i64::from(sys_num) {
921920
SYS_read | SYS_pread64 => {
922921
let h = emulator_modules.get_mut::<SnapshotModule>().unwrap();
923-
h.access(a1, a2 as usize);
922+
/*
923+
* Only note the access if the call is successful. And only mark the
924+
* portion of the buffer which has actually been modified.
925+
*/
926+
if result != GuestAddr::MAX {
927+
h.access(a1, result as usize);
928+
}
924929
}
925930
SYS_readlinkat => {
926931
let h = emulator_modules.get_mut::<SnapshotModule>().unwrap();

0 commit comments

Comments
 (0)