From d338b30c080ecfe1a6639185b6505b7a7b8edbeb Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Wed, 23 Aug 2023 19:27:58 +0100 Subject: [PATCH] qemu: add cpu page_size call (#1433) * qemu handy cpu page size call proposal. * changes from feedback. --- libafl_qemu/libafl_qemu_build/src/bindings.rs | 1 + .../src/x86_64_stub_bindings.rs | 6 +++++ libafl_qemu/src/emu.rs | 25 ++++++++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/libafl_qemu/libafl_qemu_build/src/bindings.rs b/libafl_qemu/libafl_qemu_build/src/bindings.rs index 01b7766423..a2c9ed2567 100644 --- a/libafl_qemu/libafl_qemu_build/src/bindings.rs +++ b/libafl_qemu/libafl_qemu_build/src/bindings.rs @@ -120,6 +120,7 @@ pub fn generate( .allowlist_function("syx_snapshot_root_restore") .allowlist_function("syx_snapshot_dirty_list_add") .allowlist_function("device_list_all") + .allowlist_function("qemu_target_page_size") .blocklist_function("main_loop_wait") // bindgen issue #1313 .parse_callbacks(Box::new(bindgen::CargoCallbacks)); diff --git a/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs b/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs index 07b26f7cbe..95e9e177c5 100644 --- a/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs +++ b/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs @@ -11100,6 +11100,12 @@ impl ::std::ops::BitAndAssign for qemu_plugin_mem_rw { self.0 &= rhs.0; } } + +extern "C" { + #[doc = " qemu_target_page_size - return the target's page size"] + pub fn qemu_target_page_size() -> usize; +} + #[repr(transparent)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct qemu_plugin_mem_rw(pub ::std::os::raw::c_uint); diff --git a/libafl_qemu/src/emu.rs b/libafl_qemu/src/emu.rs index 8686eaaadc..14074c3516 100644 --- a/libafl_qemu/src/emu.rs +++ b/libafl_qemu/src/emu.rs @@ -7,12 +7,16 @@ use core::{ mem::MaybeUninit, ptr::{addr_of, copy_nonoverlapping, null}, }; +use std::{cell::OnceCell, slice::from_raw_parts, str::from_utf8_unchecked}; #[cfg(emulation_mode = "systemmode")] use std::{ ffi::{CStr, CString}, ptr::null_mut, }; -use std::{slice::from_raw_parts, str::from_utf8_unchecked}; + +thread_local! { + static SNAPSHOT_PAGE_SIZE: OnceCell = OnceCell::new(); +} #[cfg(emulation_mode = "usermode")] use libc::c_int; @@ -742,6 +746,25 @@ impl CPU { pub fn raw_ptr(&self) -> CPUStatePtr { self.ptr } + + #[must_use] + pub fn page_size(&self) -> usize { + #[cfg(emulation_mode = "usermode")] + { + SNAPSHOT_PAGE_SIZE.with(|s| { + *s.get_or_init(|| { + unsafe { libc::sysconf(libc::_SC_PAGE_SIZE) } + .try_into() + .expect("Invalid page size") + }) + }) + } + #[cfg(emulation_mode = "systemmode")] + { + SNAPSHOT_PAGE_SIZE + .with(|s| *s.get_or_init(|| unsafe { libafl_qemu_sys::qemu_target_page_size() })) + } + } } static mut EMULATOR_IS_INITIALIZED: bool = false;