Make Qemu.mmap public and accept fd as the argument (#3083)

* chg mmap

* Proper error handling

* lol

* fix ci
This commit is contained in:
Dongjia "toka" Zhang 2025-03-18 12:21:11 +01:00 committed by GitHub
parent 0a923b27d2
commit d0da90cf6a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 25 additions and 17 deletions

View File

@ -1,3 +1,4 @@
use libafl_bolts::Error;
use libafl_qemu_sys::{GuestAddr, MmapPerms, VerifyAccess}; use libafl_qemu_sys::{GuestAddr, MmapPerms, VerifyAccess};
use crate::{Emulator, GuestMaps, NopSnapshotManager, TargetSignalHandling}; use crate::{Emulator, GuestMaps, NopSnapshotManager, TargetSignalHandling};
@ -68,7 +69,7 @@ impl<C, CM, ED, ET, I, S, SM> Emulator<C, CM, ED, ET, I, S, SM> {
addr: GuestAddr, addr: GuestAddr,
size: usize, size: usize,
perms: MmapPerms, perms: MmapPerms,
) -> Result<GuestAddr, String> { ) -> Result<GuestAddr, Error> {
self.qemu.map_private(addr, size, perms) self.qemu.map_private(addr, size, perms)
} }
@ -77,7 +78,7 @@ impl<C, CM, ED, ET, I, S, SM> Emulator<C, CM, ED, ET, I, S, SM> {
addr: GuestAddr, addr: GuestAddr,
size: usize, size: usize,
perms: MmapPerms, perms: MmapPerms,
) -> Result<GuestAddr, String> { ) -> Result<GuestAddr, Error> {
self.qemu.map_fixed(addr, size, perms) self.qemu.map_fixed(addr, size, perms)
} }

View File

@ -3,7 +3,7 @@ use std::{
str::from_utf8_unchecked_mut, str::from_utf8_unchecked_mut,
}; };
use libafl_bolts::os::unix_signals::Signal; use libafl_bolts::{Error, os::unix_signals::Signal};
use libafl_qemu_sys::{ use libafl_qemu_sys::{
GuestAddr, GuestUsize, IntervalTreeNode, IntervalTreeRoot, MapInfo, MmapPerms, VerifyAccess, GuestAddr, GuestUsize, IntervalTreeNode, IntervalTreeRoot, MapInfo, MmapPerms, VerifyAccess,
exec_path, free_self_maps, guest_base, libafl_force_dfl, libafl_get_brk, exec_path, free_self_maps, guest_base, libafl_force_dfl, libafl_get_brk,
@ -324,18 +324,22 @@ impl Qemu {
} }
#[expect(clippy::cast_sign_loss)] #[expect(clippy::cast_sign_loss)]
fn mmap( pub fn mmap(
self, self,
addr: GuestAddr, addr: GuestAddr,
size: usize, size: usize,
perms: MmapPerms, perms: MmapPerms,
flags: c_int, flags: c_int,
) -> Result<GuestAddr, ()> { fd: i32,
) -> Result<GuestAddr, Error> {
let res = unsafe { let res = unsafe {
libafl_qemu_sys::target_mmap(addr, size as GuestUsize, perms.into(), flags, -1, 0) libafl_qemu_sys::target_mmap(addr, size as GuestUsize, perms.into(), flags, fd, 0)
}; };
if res <= 0 { if res <= 0 {
Err(()) let errno = std::io::Error::last_os_error().raw_os_error();
Err(Error::illegal_argument(format!(
"failed to mmap addr: {addr:x} (size: {size:?} prot: {perms:?} flags: {flags:?} fd: {fd:?}). The errno is {errno:?}",
)))
} else { } else {
Ok(res as GuestAddr) Ok(res as GuestAddr)
} }
@ -346,10 +350,14 @@ impl Qemu {
addr: GuestAddr, addr: GuestAddr,
size: usize, size: usize,
perms: MmapPerms, perms: MmapPerms,
) -> Result<GuestAddr, String> { ) -> Result<GuestAddr, Error> {
self.mmap(addr, size, perms, libc::MAP_PRIVATE | libc::MAP_ANONYMOUS) self.mmap(
.map_err(|()| format!("Failed to map {addr}")) addr,
.map(|addr| addr as GuestAddr) size,
perms,
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
-1,
)
} }
pub fn map_fixed( pub fn map_fixed(
@ -357,15 +365,14 @@ impl Qemu {
addr: GuestAddr, addr: GuestAddr,
size: usize, size: usize,
perms: MmapPerms, perms: MmapPerms,
) -> Result<GuestAddr, String> { ) -> Result<GuestAddr, Error> {
self.mmap( self.mmap(
addr, addr,
size, size,
perms, perms,
libc::MAP_FIXED | libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, libc::MAP_FIXED | libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
-1,
) )
.map_err(|()| format!("Failed to map {addr}"))
.map(|addr| addr as GuestAddr)
} }
pub fn mprotect(&self, addr: GuestAddr, size: usize, perms: MmapPerms) -> Result<(), String> { pub fn mprotect(&self, addr: GuestAddr, size: usize, perms: MmapPerms) -> Result<(), String> {
@ -532,7 +539,7 @@ pub mod pybind {
if let Ok(p) = MmapPerms::try_from(perms) { if let Ok(p) = MmapPerms::try_from(perms) {
self.qemu self.qemu
.map_private(addr, size, p) .map_private(addr, size, p)
.map_err(PyValueError::new_err) .map_err(|_| PyValueError::new_err("Failed to mmap"))
} else { } else {
Err(PyValueError::new_err("Invalid perms")) Err(PyValueError::new_err("Invalid perms"))
} }
@ -541,8 +548,8 @@ pub mod pybind {
fn map_fixed(&self, addr: GuestAddr, size: usize, perms: i32) -> PyResult<GuestAddr> { fn map_fixed(&self, addr: GuestAddr, size: usize, perms: i32) -> PyResult<GuestAddr> {
if let Ok(p) = MmapPerms::try_from(perms) { if let Ok(p) = MmapPerms::try_from(perms) {
self.qemu self.qemu
.map_fixed(addr, size, p) .map_private(addr, size, p)
.map_err(PyValueError::new_err) .map_err(|_| PyValueError::new_err("Failed to mmap"))
} else { } else {
Err(PyValueError::new_err("Invalid perms")) Err(PyValueError::new_err("Invalid perms"))
} }