Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incorrect handling of brk syscall when shrinking the heap #2776

Merged
merged 5 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libafl_qemu/libafl_qemu_build/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::cargo_add_rpath;

pub const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge";
pub const QEMU_DIRNAME: &str = "qemu-libafl-bridge";
pub const QEMU_REVISION: &str = "b01a0bc334cf11bfc5e8f121d9520ef7f47dbcd1";
pub const QEMU_REVISION: &str = "06bf8facec33548840413fba1b20858f58e38e2d";

#[allow(clippy::module_name_repetitions)]
pub struct BuildResult {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5705,6 +5705,9 @@ extern "C" {
extern "C" {
pub fn libafl_get_brk() -> u64;
}
extern "C" {
pub fn libafl_get_initial_brk() -> u64;
}
extern "C" {
pub fn libafl_set_brk(new_brk: u64) -> u64;
}
Expand Down
5 changes: 5 additions & 0 deletions libafl_qemu/src/emu/usermode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ where
self.qemu.get_brk()
}

#[must_use]
pub fn get_initial_brk(&self) -> GuestAddr {
self.qemu.get_initial_brk()
}

pub fn set_brk(&self, brk: GuestAddr) {
self.qemu.set_brk(brk);
}
Expand Down
15 changes: 12 additions & 3 deletions libafl_qemu/src/modules/usermode/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ pub struct SnapshotModule {
pub maps: MappingInfo,
pub new_maps: Mutex<MappingInfo>,
pub pages: HashMap<GuestAddr, SnapshotPageInfo>,
pub initial_brk: GuestAddr,
pub brk: GuestAddr,
pub mmap_start: GuestAddr,
pub mmap_limit: usize,
Expand Down Expand Up @@ -120,6 +121,7 @@ impl SnapshotModule {
maps: MappingInfo::default(),
new_maps: Mutex::new(MappingInfo::default()),
pages: HashMap::default(),
initial_brk: 0,
brk: 0,
mmap_start: 0,
mmap_limit: 0,
Expand All @@ -137,6 +139,7 @@ impl SnapshotModule {
maps: MappingInfo::default(),
new_maps: Mutex::new(MappingInfo::default()),
pages: HashMap::default(),
initial_brk: 0,
brk: 0,
mmap_start: 0,
mmap_limit: 0,
Expand All @@ -154,6 +157,7 @@ impl SnapshotModule {
maps: MappingInfo::default(),
new_maps: Mutex::new(MappingInfo::default()),
pages: HashMap::default(),
initial_brk: 0,
brk: 0,
mmap_start: 0,
mmap_limit,
Expand Down Expand Up @@ -191,6 +195,7 @@ impl SnapshotModule {
pub fn snapshot(&mut self, qemu: Qemu) {
log::info!("Start snapshot");
self.brk = qemu.get_brk();
self.initial_brk = qemu.get_initial_brk();
self.mmap_start = qemu.get_mmap_start();
self.pages.clear();
for map in qemu.mappings() {
Expand Down Expand Up @@ -843,12 +848,16 @@ where
}
SYS_brk => {
let h = emulator_modules.get_mut::<SnapshotModule>().unwrap();
if h.brk != result && result != 0 {
/* brk has changed. we change mapping from the snapshotted brk address to the new target_brk
if h.brk != result && result != 0 && result > h.initial_brk {
/* brk has changed, and it doesn't shrink below initial_brk. We change mapping from the snapshotted initial brk address to the new target_brk
* If no brk mapping has been made until now, change_mapped won't change anything and just create a new mapping.
* It is safe to assume RW perms here
*/
h.change_mapped(h.brk, (result - h.brk) as usize, Some(MmapPerms::ReadWrite));
h.change_mapped(
h.initial_brk,
(result - h.initial_brk) as usize,
Some(MmapPerms::ReadWrite),
);
}
}
// mmap syscalls
Expand Down
13 changes: 9 additions & 4 deletions libafl_qemu/src/qemu/usermode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use std::{
};

use libafl_qemu_sys::{
exec_path, free_self_maps, guest_base, libafl_force_dfl, libafl_get_brk, libafl_load_addr,
libafl_maps_first, libafl_maps_next, libafl_qemu_run, libafl_set_brk, mmap_next_start,
pageflags_get_root, read_self_maps, GuestAddr, GuestUsize, IntervalTreeNode, IntervalTreeRoot,
MapInfo, MmapPerms, VerifyAccess,
exec_path, free_self_maps, guest_base, libafl_force_dfl, libafl_get_brk,
libafl_get_initial_brk, libafl_load_addr, libafl_maps_first, libafl_maps_next, libafl_qemu_run,
libafl_set_brk, mmap_next_start, pageflags_get_root, read_self_maps, GuestAddr, GuestUsize,
IntervalTreeNode, IntervalTreeRoot, MapInfo, MmapPerms, VerifyAccess,
};
use libc::{c_int, c_uchar, strlen};
#[cfg(feature = "python")]
Expand Down Expand Up @@ -177,6 +177,11 @@ impl Qemu {
unsafe { libafl_get_brk() as GuestAddr }
}

#[must_use]
pub fn get_initial_brk(&self) -> GuestAddr {
unsafe { libafl_get_initial_brk() as GuestAddr }
}

pub fn set_brk(&self, brk: GuestAddr) {
unsafe { libafl_set_brk(brk.into()) };
}
Expand Down
Loading