From efd0ea1ba18a2999621210113d39f5e48d164f36 Mon Sep 17 00:00:00 2001 From: Evian-Zhang Date: Thu, 15 May 2025 09:55:13 +0800 Subject: [PATCH 1/2] Fix android shmem --- libafl_targets/src/android-ashmem.h | 81 ----------------------------- libafl_targets/src/forkserver.rs | 42 ++++++++++++++- 2 files changed, 40 insertions(+), 83 deletions(-) delete mode 100644 libafl_targets/src/android-ashmem.h diff --git a/libafl_targets/src/android-ashmem.h b/libafl_targets/src/android-ashmem.h deleted file mode 100644 index e3deb1db349..00000000000 --- a/libafl_targets/src/android-ashmem.h +++ /dev/null @@ -1,81 +0,0 @@ -/// On Android, this file redirects all (unsupported) shared memory calls out to -/// Android's Ashmem. Source: -/// -#ifdef __ANDROID__ - #ifndef _ANDROID_ASHMEM_H - #define _ANDROID_ASHMEM_H - - // Not supported on Android. - #undef USEMMAP - - #ifndef _GNU_SOURCE - #define _GNU_SOURCE - #endif - #include - #include - #include - #include - #include - #include - #include - #include - #define ASHMEM_DEVICE "/dev/ashmem" - -int shmdt(const void *address) { - #if defined(SYS_shmdt) - return syscall(SYS_shmdt, address); - #else - return syscall(SYS_ipc, SHMDT, 0, 0, 0, address, 0); - #endif -} - -int shmctl(int __shmid, int __cmd, struct shmid_ds *__buf) { - int ret = 0; - if (__cmd == IPC_RMID) { - int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); - struct ashmem_pin pin = {0, length}; - ret = ioctl(__shmid, ASHMEM_UNPIN, &pin); - close(__shmid); - } - - return ret; -} - -int shmget(key_t __key, size_t __size, int __shmflg) { - (void)__shmflg; - int fd, ret; - char ourkey[11]; - - fd = open(ASHMEM_DEVICE, O_RDWR); - if (fd < 0) return fd; - - sprintf(ourkey, "%d", __key); - ret = ioctl(fd, ASHMEM_SET_NAME, ourkey); - if (ret < 0) goto error; - - ret = ioctl(fd, ASHMEM_SET_SIZE, __size); - if (ret < 0) goto error; - - return fd; - -error: - close(fd); - return ret; -} - -void *shmat(int __shmid, const void *__shmaddr, int __shmflg) { - (void)__shmflg; - int size; - void *ptr; - - size = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); - if (size < 0) { return NULL; } - - ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, __shmid, 0); - if (ptr == MAP_FAILED) { return NULL; } - - return ptr; -} - - #endif /* !_ANDROID_ASHMEM_H */ -#endif /* !__ANDROID__ */ diff --git a/libafl_targets/src/forkserver.rs b/libafl_targets/src/forkserver.rs index b2c1f18b783..8c148eea264 100644 --- a/libafl_targets/src/forkserver.rs +++ b/libafl_targets/src/forkserver.rs @@ -9,11 +9,15 @@ use std::{ use libafl::{ Error, executors::forkserver::{ - FORKSRV_FD, FS_ERROR_SHM_OPEN, FS_NEW_OPT_AUTODTCT, FS_NEW_OPT_MAPSIZE, - FS_NEW_OPT_SHDMEM_FUZZ, FS_NEW_VERSION_MAX, FS_OPT_ERROR, SHM_CMPLOG_ENV_VAR, SHM_ENV_VAR, + FORKSRV_FD, FS_ERROR_SHM_OPEN, FS_NEW_OPT_MAPSIZE, + FS_NEW_OPT_SHDMEM_FUZZ, FS_NEW_VERSION_MAX, FS_OPT_ERROR, SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, }, }; +#[cfg(feature = "cmplog")] +use libafl::SHM_CMPLOG_ENV_VAR; +#[cfg(any(target_os = "linux", target_vendor = "apple"))] +use libafl::FS_NEW_OPT_AUTODTCT; use libafl_bolts::os::{ChildHandle, ForkResult}; use nix::{ sys::signal::{SigHandler, Signal}, @@ -51,6 +55,7 @@ fn write_to_forkserver(message: &[u8]) -> Result<(), Error> { } Ok(()) } +#[cfg(any(target_os = "linux", target_vendor = "apple"))] fn write_all_to_forkserver(message: &[u8]) -> Result<(), Error> { let mut remain_len = message.len(); while remain_len > 0 { @@ -86,6 +91,30 @@ fn read_u32_from_forkserver() -> Result { Ok(u32::from_ne_bytes(buf)) } +#[cfg(target_os = "android")] +const ASHMEM_GET_SIZE: core::ffi::c_int = 0x00007704; +#[cfg(target_os = "android")] +unsafe fn android_shmat(shm_id: i32) -> *mut core::ffi::c_void { + let size = unsafe { libc::ioctl(shm_id, ASHMEM_GET_SIZE) }; + if size < 0 { + return core::ptr::null_mut(); + } + let ptr = unsafe { + libc::mmap( + core::ptr::null_mut(), + size as usize, + libc::PROT_READ | libc::PROT_WRITE, + libc::MAP_SHARED, + shm_id, + 0, + ) + }; + if core::ptr::eq(ptr, libc::MAP_FAILED) { + return core::ptr::null_mut(); + } + ptr +} + /// Guard [`map_shared_memory`] is invoked only once static SHM_MAP_GUARD: OnceLock<()> = OnceLock::new(); @@ -112,7 +141,10 @@ fn map_shared_memory_internal() -> Result<(), Error> { write_error_to_forkserver(FS_ERROR_SHM_OPEN)?; return Err(Error::illegal_argument("Invalid __AFL_SHM_ID value")); }; + #[cfg(not(target_os = "android"))] let map = unsafe { libc::shmat(shm_id, core::ptr::null(), 0) }; + #[cfg(target_os = "android")] + let map = unsafe { android_shmat(shm_id) }; if map.is_null() || core::ptr::eq(map, libc::MAP_FAILED) { write_error_to_forkserver(FS_ERROR_SHM_OPEN)?; return Err(Error::illegal_state("shmat for map")); @@ -149,7 +181,10 @@ fn map_input_shared_memory_internal() -> Result<(), Error> { write_error_to_forkserver(FS_ERROR_SHM_OPEN)?; return Err(Error::illegal_argument("Invalid __AFL_SHM_FUZZ_ID value")); }; + #[cfg(not(target_os = "android"))] let map = unsafe { libc::shmat(shm_id, core::ptr::null(), 0) }; + #[cfg(target_os = "android")] + let map = unsafe { android_shmat(shm_id) }; if map.is_null() || core::ptr::eq(map, libc::MAP_FAILED) { write_error_to_forkserver(FS_ERROR_SHM_OPEN)?; return Err(Error::illegal_state( @@ -193,7 +228,10 @@ fn map_cmplog_shared_memory_internal() -> Result<(), Error> { write_error_to_forkserver(FS_ERROR_SHM_OPEN)?; return Err(Error::illegal_argument("Invalid __AFL_CMPLOG_SHM_ID value")); }; + #[cfg(not(target_os = "android"))] let map = unsafe { libc::shmat(shm_id, core::ptr::null(), 0) }; + #[cfg(target_os = "android")] + let map = unsafe { android_shmat(shm_id) }; if map.is_null() || core::ptr::eq(map, libc::MAP_FAILED) { write_error_to_forkserver(FS_ERROR_SHM_OPEN)?; return Err(Error::illegal_state("shmat for map")); From ddaff24f9592d074624bd6f248deb7b8d87ef2a9 Mon Sep 17 00:00:00 2001 From: Evian-Zhang Date: Thu, 15 May 2025 10:17:37 +0800 Subject: [PATCH 2/2] Fix silly typo --- libafl_targets/src/forkserver.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libafl_targets/src/forkserver.rs b/libafl_targets/src/forkserver.rs index 8c148eea264..0c89b743a89 100644 --- a/libafl_targets/src/forkserver.rs +++ b/libafl_targets/src/forkserver.rs @@ -15,9 +15,9 @@ use libafl::{ }, }; #[cfg(feature = "cmplog")] -use libafl::SHM_CMPLOG_ENV_VAR; +use libafl::executors::forkserver::SHM_CMPLOG_ENV_VAR; #[cfg(any(target_os = "linux", target_vendor = "apple"))] -use libafl::FS_NEW_OPT_AUTODTCT; +use libafl::executors::forkserver::FS_NEW_OPT_AUTODTCT; use libafl_bolts::os::{ChildHandle, ForkResult}; use nix::{ sys::signal::{SigHandler, Signal},