diff --git a/libafl/src/executors/forkserver.rs b/libafl/src/executors/forkserver.rs index fbf85f3f63..0ceecc103f 100644 --- a/libafl/src/executors/forkserver.rs +++ b/libafl/src/executors/forkserver.rs @@ -907,7 +907,7 @@ where "Failed to read map size from forkserver".to_string(), )); } - self.set_map_size(fsrv_map_size); + self.set_map_size(fsrv_map_size)?; } if status & FS_NEW_OPT_SHDMEM_FUZZ != 0 { @@ -973,7 +973,7 @@ where ) -> Result<(), Error> { if status & FS_OPT_ENABLED == FS_OPT_ENABLED && status & FS_OPT_MAPSIZE == FS_OPT_MAPSIZE { let fsrv_map_size = fs_opt_get_mapsize(status); - self.set_map_size(fsrv_map_size); + self.set_map_size(fsrv_map_size)?; } // Only with SHMEM or AUTODICT we can send send_status back or it breaks! @@ -1041,7 +1041,7 @@ where } #[allow(clippy::cast_sign_loss)] - fn set_map_size(&mut self, fsrv_map_size: i32) { + fn set_map_size(&mut self, fsrv_map_size: i32) -> Result { // When 0, we assume that map_size was filled by the user or const /* TODO autofill map size from the observer @@ -1049,16 +1049,30 @@ where self.map_size = Some(fsrv_map_size as usize); } */ - let mut map_size = fsrv_map_size; - if map_size % 64 != 0 { - map_size = ((map_size + 63) >> 6) << 6; + let mut actual_map_size = fsrv_map_size; + if actual_map_size % 64 != 0 { + actual_map_size = ((actual_map_size + 63) >> 6) << 6; } // TODO set AFL_MAP_SIZE - assert!(self.map_size.is_none() || map_size as usize <= self.map_size.unwrap()); + if let Some(max_size) = self.map_size { + if actual_map_size as usize > max_size { + return Err(Error::illegal_state(format!( + "The target map size is {actual_map_size} but the allocated map size is {max_size}. \ + Increase the initial size of the forkserver map to at least that size using the forkserver builder's `coverage_map_size`." + ))); + } + } else { + return Err(Error::illegal_state(format!( + "The target map size is {actual_map_size} but we did not create a coverage map before launching the target! \ + Set an initial forkserver map to at least that size using the forkserver builder's `coverage_map_size`." + ))); + } // we'll use this later when we truncate the observer - self.map_size = Some(map_size as usize); + self.map_size = Some(actual_map_size as usize); + + Ok(actual_map_size as usize) } /// Use autodict?