diff --git a/libafl_frida/src/alloc.rs b/libafl_frida/src/alloc.rs index 733a92a70d..f9c4ae2bb9 100644 --- a/libafl_frida/src/alloc.rs +++ b/libafl_frida/src/alloc.rs @@ -28,6 +28,7 @@ pub struct Allocator { shadow_pages: RangeSet, allocation_queue: HashMap>, largest_allocation: usize, + total_allocation_size: usize, base_mapping_addr: usize, current_mapping_addr: usize, } @@ -70,7 +71,7 @@ impl Allocator { let mut shadow_bit = 0; #[cfg(all(target_arch = "aarch64", target_os = "android"))] - for try_shadow_bit in &[46usize, 36usize] { + for try_shadow_bit in &[44usize, 36usize] { let addr: usize = 1 << try_shadow_bit; if unsafe { mmap( @@ -147,6 +148,7 @@ impl Allocator { shadow_pages: RangeSet::new(), allocation_queue: HashMap::new(), largest_allocation: 0, + total_allocation_size: 0, base_mapping_addr: addr + addr + addr, current_mapping_addr: addr + addr + addr, } @@ -205,6 +207,11 @@ impl Allocator { } let rounded_up_size = self.round_up_to_page(size) + 2 * self.page_size; + if self.total_allocation_size + rounded_up_size > self.options.asan_max_total_allocation() { + return std::ptr::null_mut(); + } + self.total_allocation_size += rounded_up_size; + let metadata = if let Some(mut metadata) = self.find_smallest_fit(rounded_up_size) { //println!("reusing allocation at {:x}, (actual mapping starts at {:x}) size {:x}", metadata.address, metadata.address - self.page_size, size); metadata.is_malloc_zero = is_malloc_zero; @@ -345,6 +352,8 @@ impl Allocator { for allocation in tmp_allocations { self.allocations.insert(allocation.address, allocation); } + + self.total_allocation_size = 0; } pub fn get_usable_size(&self, ptr: *mut c_void) -> usize { diff --git a/libafl_frida/src/lib.rs b/libafl_frida/src/lib.rs index 70915cbc95..58fed4ff98 100644 --- a/libafl_frida/src/lib.rs +++ b/libafl_frida/src/lib.rs @@ -39,6 +39,7 @@ pub struct FridaOptions { enable_asan_continue_after_error: bool, enable_asan_allocation_backtraces: bool, asan_max_allocation: usize, + asan_max_total_allocation: usize, asan_max_allocation_panics: bool, enable_coverage: bool, enable_drcov: bool, @@ -81,6 +82,9 @@ impl FridaOptions { "asan-max-allocation" => { options.asan_max_allocation = value.parse().unwrap(); } + "asan-max-total-allocation" => { + options.asan_max_total_allocation = value.parse().unwrap(); + } "asan-max-allocation-panics" => { options.asan_max_allocation_panics = value.parse().unwrap(); } @@ -210,6 +214,13 @@ impl FridaOptions { self.asan_max_allocation } + /// The maximum total allocation size that the ASAN allocator should allocate + #[must_use] + #[inline] + pub fn asan_max_total_allocation(&self) -> usize { + self.asan_max_total_allocation + } + /// Should we panic if the max ASAN allocation size is exceeded #[must_use] #[inline] @@ -254,6 +265,7 @@ impl Default for FridaOptions { enable_asan_continue_after_error: false, enable_asan_allocation_backtraces: true, asan_max_allocation: 1 << 30, + asan_max_total_allocation: 1 << 32, asan_max_allocation_panics: false, enable_coverage: true, enable_drcov: false,