Skip to content

Commit c879a0a

Browse files
authored
Fix frida ASAN incompatibility with mac m1 (AFLplusplus#917)
Add MAP_JIT, and extract the writable portion of generate_instrumentation_blobs into AsanRuntime
1 parent 2a2e70a commit c879a0a

File tree

1 file changed

+51
-25
lines changed

1 file changed

+51
-25
lines changed

libafl_frida/src/asan/asan_rt.rs

+51-25
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ pub const ASAN_SAVE_REGISTER_NAMES: [&str; ASAN_SAVE_REGISTER_COUNT] = [
103103
#[cfg(target_arch = "aarch64")]
104104
pub const ASAN_SAVE_REGISTER_COUNT: usize = 32;
105105

106+
#[cfg(target_arch = "aarch64")]
107+
const ASAN_EH_FRAME_DWORD_COUNT: usize = 14;
108+
#[cfg(target_arch = "aarch64")]
109+
const ASAN_EH_FRAME_FDE_OFFSET: u32 = 20;
110+
#[cfg(target_arch = "aarch64")]
111+
const ASAN_EH_FRAME_FDE_ADDRESS_OFFSET: u32 = 28;
112+
106113
/// The frida address sanitizer runtime, providing address sanitization.
107114
/// When executing in `ASAN`, each memory access will get checked, using frida stalker under the hood.
108115
/// The runtime can report memory errors that occurred during execution,
@@ -131,6 +138,9 @@ pub struct AsanRuntime {
131138
module_map: Option<ModuleMap>,
132139
suppressed_addresses: Vec<usize>,
133140
shadow_check_func: Option<extern "C" fn(*const c_void, usize) -> bool>,
141+
142+
#[cfg(target_arch = "aarch64")]
143+
eh_frame: [u32; ASAN_EH_FRAME_DWORD_COUNT],
134144
}
135145

136146
impl Debug for AsanRuntime {
@@ -304,6 +314,9 @@ impl AsanRuntime {
304314
module_map: None,
305315
suppressed_addresses: Vec::new(),
306316
shadow_check_func: None,
317+
318+
#[cfg(target_arch = "aarch64")]
319+
eh_frame: [0; ASAN_EH_FRAME_DWORD_COUNT],
307320
}
308321
}
309322

@@ -1641,18 +1654,33 @@ impl AsanRuntime {
16411654
);
16421655

16431656
let blob = ops.finalize().unwrap();
1657+
let mut map_flags = MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE;
1658+
1659+
// apple aarch64 requires MAP_JIT to allocates WX pages
1660+
#[cfg(all(target_vendor = "apple", target_arch = "aarch64"))]
1661+
map_flags |= MapFlags::MAP_JIT;
1662+
16441663
unsafe {
16451664
let mapping = mmap(
16461665
std::ptr::null_mut(),
16471666
0x1000,
16481667
ProtFlags::all(),
1649-
MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE,
1668+
map_flags,
16501669
-1,
16511670
0,
16521671
)
16531672
.unwrap();
1673+
1674+
// on apple aarch64, WX pages can't be both writable and executable at the same time.
1675+
// pthread_jit_write_protect_np flips them from executable (1) to writable (0)
1676+
#[cfg(all(target_vendor = "apple", target_arch = "aarch64"))]
1677+
libc::pthread_jit_write_protect_np(0);
1678+
16541679
blob.as_ptr()
16551680
.copy_to_nonoverlapping(mapping as *mut u8, blob.len());
1681+
1682+
#[cfg(all(target_vendor = "apple", target_arch = "aarch64"))]
1683+
libc::pthread_jit_write_protect_np(1);
16561684
self.shadow_check_func = Some(std::mem::transmute(mapping as *mut u8));
16571685
}
16581686
}
@@ -1967,8 +1995,10 @@ impl AsanRuntime {
19671995
; stp x0, x1, [x28]
19681996

19691997
; adr x25, <report
1970-
; adr x0, >eh_frame_fde
1971-
; adr x27, >fde_address
1998+
; adr x15, >eh_frame_cie_addr
1999+
; ldr x15, [x15]
2000+
; add x0, x15, ASAN_EH_FRAME_FDE_OFFSET // eh_frame_fde
2001+
; add x27, x15, ASAN_EH_FRAME_FDE_ADDRESS_OFFSET // fde_address
19722002
; ldr w26, [x27]
19732003
; cmp w26, #0x0
19742004
; b.ne >skip_register
@@ -2013,29 +2043,25 @@ impl AsanRuntime {
20132043
; .qword AsanRuntime::handle_trap as *mut c_void as i64
20142044
; register_frame_func:
20152045
; .qword __register_frame as *mut c_void as i64
2016-
; eh_frame_cie:
2017-
; .dword 0x14
2018-
; .dword 0x00
2019-
; .dword 0x00527a01
2020-
; .dword 0x011e7c01
2021-
; .dword 0x001f0c1b
2022-
; eh_frame_fde:
2023-
; .dword 0x14
2024-
; .dword 0x18
2025-
; fde_address:
2026-
; .dword 0x0 // <-- address offset goes here
2027-
; .dword 0x104
2028-
//advance_loc 12
2029-
//def_cfa r29 (x29) at offset 16
2030-
//offset r30 (x30) at cfa-8
2031-
//offset r29 (x29) at cfa-16
2032-
; .dword 0x1d0c4c00
2033-
; .dword 0x9d029e10u32 as i32
2034-
; .dword 0x04
2035-
// empty next FDE:
2036-
; .dword 0x0
2037-
; .dword 0x0
2046+
; eh_frame_cie_addr:
2047+
; .qword addr_of_mut!(self.eh_frame) as i64
20382048
);
2049+
self.eh_frame = [
2050+
0x14, 0, 0x00527a01, 0x011e7c01, 0x001f0c1b,
2051+
// eh_frame_fde
2052+
0x14, 0x18,
2053+
// fde_address
2054+
0, // <-- address offset goes here
2055+
0x104,
2056+
// advance_loc 12
2057+
// def_cfa r29 (x29) at offset 16
2058+
// offset r30 (x30) at cfa-8
2059+
// offset r29 (x29) at cfa-16
2060+
0x1d0c4c00, 0x9d029e10, 0x4,
2061+
// empty next FDE:
2062+
0, 0
2063+
];
2064+
20392065
self.blob_report = Some(ops_report.finalize().unwrap().into_boxed_slice());
20402066

20412067
self.blob_check_mem_byte = Some(self.generate_shadow_check_blob(0));

0 commit comments

Comments
 (0)