LibAFL QEMU update to v10.0.0 (#3181)

* update qemu hash

* clippy, fmt

* update

* Revert "Update hashbrown requirement from 0.14.5 to 0.15.3 (#3184)" (#3186)

This reverts commit 4448799dc2205e4cb1753b8b8d91b4f6d299365d.

* update qemu

* fix systemmode

* update qemu

* update qemu

* update qemu with fix

* debug

* cargo hack

* FMT

---------

Co-authored-by: Dongjia Zhang <tokazerkje@outlook.com>
This commit is contained in:
Romain Malmain 2025-05-12 07:58:11 -07:00 committed by GitHub
parent 0d962bc561
commit c9b0dc216f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 1544 additions and 1343 deletions

View File

@ -23,9 +23,10 @@ runs:
- name: Add nightly clippy
shell: bash
run: rustup toolchain install nightly --component clippy --allow-downgrade
- name: Install cargo-hack
- uses: taiki-e/install-action@cargo-hack
- name: Add nightly
shell: bash
run: curl -LsSf https://github.com/taiki-e/cargo-hack/releases/latest/download/cargo-hack-x86_64-unknown-linux-gnu.tar.gz | tar xzf - -C ~/.cargo/bin
run: rustup toolchain install nightly --allow-downgrade
- name: Default to nightly
shell: bash
run: rustup default nightly

View File

@ -53,9 +53,8 @@ const WRAPPER_HEADER: &str = r#"
#include "migration/savevm.h"
#include "hw/core/sysemu-cpu-ops.h"
#include "exec/address-spaces.h"
#include "sysemu/tcg.h"
#include "sysemu/runstate.h"
#include "sysemu/replay.h"
#include "exec/target_page.h"
#include "system/system.h"
#include "libafl/system.h"
#include "libafl/qemu_snapshot.h"
@ -67,11 +66,9 @@ const WRAPPER_HEADER: &str = r#"
#include "exec/cpu-common.h"
#include "exec/cpu-all.h"
#include "exec/exec-all.h"
#include "exec/translate-all.h"
#include "exec/log.h"
#include "trace/trace-root.h"
#include "qemu/accel.h"
#include "hw/core/accel-cpu.h"
#include "tcg/tcg.h"
#include "tcg/tcg-op.h"
@ -122,6 +119,7 @@ pub fn generate(
.derive_default(true)
.impl_debug(true)
.generate_comments(true)
.wrap_static_fns(true)
.default_enum_style(bindgen::EnumVariation::NewType {
is_global: true,
is_bitfield: true,

View File

@ -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 = "97bef506eed24ee8d0eda4a07c4419c55dae4acb";
pub const QEMU_REVISION: &str = "0bea78a122b249cbffafdb130af04cc7331c9aee";
pub struct BuildResult {
pub qemu_path: PathBuf,

View File

@ -6,6 +6,7 @@
#![expect(improper_ctypes)]
#![expect(unsafe_op_in_unsafe_fn)]
#![allow(unused_imports)]
#![allow(unnecessary_transmutes)]
#[cfg(all(not(feature = "clippy"), target_os = "linux"))]
#[rustfmt::skip]

View File

@ -1,5 +1,5 @@
/* 1.87.0-nightly */
/* qemu git hash: 97bef506eed24ee8d0eda4a07c4419c55dae4acb */
/* 1.88.0-nightly */
/* qemu git hash: 93663809156a33475ade972cdd5b1301b9310687 */
/* automatically generated by rust-bindgen 0.71.1 */
#[repr(C)]
@ -661,17 +661,19 @@ impl Default for _IO_FILE {
impl _IO_FILE {
#[inline]
pub fn _flags2(&self) -> ::std::os::raw::c_int {
u32::cast_signed(self._bitfield_1.get(0usize, 24u8) as u32)
unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 24u8) as u32) }
}
#[inline]
pub fn set__flags2(&mut self, val: ::std::os::raw::c_int) {
let val: u32 = i32::cast_unsigned(val);
unsafe {
let val: u32 = ::std::mem::transmute(val);
self._bitfield_1.set(0usize, 24u8, val as u64)
}
}
#[inline]
pub unsafe fn _flags2_raw(this: *const Self) -> ::std::os::raw::c_int {
unsafe {
u32::cast_signed(<__BindgenBitfieldUnit<[u8; 3usize]>>::raw_get(
::std::mem::transmute(<__BindgenBitfieldUnit<[u8; 3usize]>>::raw_get(
::std::ptr::addr_of!((*this)._bitfield_1),
0usize,
24u8,
@ -681,7 +683,7 @@ impl _IO_FILE {
#[inline]
pub unsafe fn set__flags2_raw(this: *mut Self, val: ::std::os::raw::c_int) {
unsafe {
let val: u32 = i32::cast_unsigned(val);
let val: u32 = ::std::mem::transmute(val);
<__BindgenBitfieldUnit<[u8; 3usize]>>::raw_set(
::std::ptr::addr_of_mut!((*this)._bitfield_1),
0usize,
@ -694,7 +696,7 @@ impl _IO_FILE {
pub fn new_bitfield_1(_flags2: ::std::os::raw::c_int) -> __BindgenBitfieldUnit<[u8; 3usize]> {
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default();
__bindgen_bitfield_unit.set(0usize, 24u8, {
let _flags2: u32 = i32::cast_unsigned(_flags2);
let _flags2: u32 = unsafe { ::std::mem::transmute(_flags2) };
_flags2 as u64
});
__bindgen_bitfield_unit

View File

@ -1,5 +1,5 @@
/* 1.87.0-nightly */
/* qemu git hash: 97bef506eed24ee8d0eda4a07c4419c55dae4acb */
/* 1.88.0-nightly */
/* qemu git hash: 93663809156a33475ade972cdd5b1301b9310687 */
/* automatically generated by rust-bindgen 0.71.1 */
#[repr(C)]

View File

@ -44,6 +44,7 @@ mod bindings {
#![expect(clippy::all)]
#![expect(clippy::pedantic)]
#![allow(unsafe_op_in_unsafe_fn)]
#![allow(unnecessary_transmutes)]
include!(concat!(env!("OUT_DIR"), "/libafl_qemu_bindings.rs"));
}

View File

@ -49,6 +49,7 @@ pub(crate) mod bindings {
#![allow(unused_variables)]
#![expect(clippy::all)]
#![expect(clippy::pedantic)]
#![allow(unnecessary_transmutes)]
include!(concat!(env!("OUT_DIR"), "/nyx_bindings.rs"));
}

View File

@ -77,7 +77,8 @@ where
qemu: Qemu,
arch_regs_map: &'static EnumMap<ExitArgs, Regs>,
) -> Result<Self::OutputCommand, CommandError> {
let input_virt_addr: GuestVirtAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?.into();
let input_virt_addr: GuestVirtAddr =
qemu.read_reg(arch_regs_map[ExitArgs::Arg1])? as GuestVirtAddr;
let max_input_size: GuestReg = qemu.read_reg(arch_regs_map[ExitArgs::Arg2])?;
Ok(InputCommand::new(
@ -134,7 +135,8 @@ where
qemu: Qemu,
arch_regs_map: &'static EnumMap<ExitArgs, Regs>,
) -> Result<Self::OutputCommand, CommandError> {
let input_virt_addr: GuestVirtAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?.into();
let input_virt_addr: GuestVirtAddr =
qemu.read_reg(arch_regs_map[ExitArgs::Arg1])? as GuestVirtAddr;
let max_input_size: GuestReg = qemu.read_reg(arch_regs_map[ExitArgs::Arg2])?;
Ok(StartCommand::new(QemuMemoryChunk::virt(

View File

@ -6,7 +6,7 @@ use libafl_qemu_sys::GuestVirtAddr;
use libc::c_uint;
use crate::{
IsSnapshotManager, NyxEmulatorDriver, Qemu, QemuMemoryChunk, Regs,
GuestReg, IsSnapshotManager, NyxEmulatorDriver, Qemu, QemuMemoryChunk, Regs,
command::{
CommandError, NativeExitKind,
nyx::{
@ -26,7 +26,7 @@ fn get_guest_string(qemu: Qemu, string_ptr_reg: Regs) -> Result<String, CommandE
let mut msg_chunk: [u8; bindings::HPRINTF_MAX_SIZE as usize] =
[0; bindings::HPRINTF_MAX_SIZE as usize];
qemu.read_mem(str_addr, &mut msg_chunk)?;
qemu.read_mem(str_addr.try_into().unwrap(), &mut msg_chunk)?;
Ok(CStr::from_bytes_until_nul(&msg_chunk)
.unwrap()
@ -117,7 +117,7 @@ where
// # Safety
// Range submit is represented with an array of 3 u64 in the Nyx API.
let allowed_range: [u64; 3] = unsafe { qemu.read_mem_val(allowed_range_addr)? };
let allowed_range: [u64; 3] = unsafe { qemu.read_mem_val(allowed_range_addr as u64)? };
Ok(RangeSubmitCommand::new(allowed_range[0]..allowed_range[1]))
}
@ -245,7 +245,7 @@ where
Ok(GetHostConfigCommand::new(QemuMemoryChunk::virt(
host_config_addr,
GuestVirtAddr::try_from(size_of::<bindings::host_config_t>()).unwrap(),
GuestReg::try_from(size_of::<bindings::host_config_t>()).unwrap(),
qemu.current_cpu().unwrap(),
)))
}
@ -270,7 +270,7 @@ where
// # Safety
// We use the C struct directly to get the agent config
let agent_config: bindings::agent_config_t =
unsafe { qemu.read_mem_val(agent_config_addr)? };
unsafe { qemu.read_mem_val(agent_config_addr as u64)? };
Ok(SetAgentConfigCommand::new(agent_config))
}

View File

@ -916,7 +916,7 @@ impl Qemu {
#[cfg(feature = "systemmode")]
pub fn set_hw_breakpoint(&self, addr: GuestAddr) -> Result<(), Error> {
let ret = unsafe { libafl_qemu_set_hw_breakpoint(addr.into()) };
let ret = unsafe { libafl_qemu_set_hw_breakpoint(addr as GuestVirtAddr) };
match ret {
0 => Ok(()),
errno => Err(Error::unsupported(format!(
@ -927,7 +927,7 @@ impl Qemu {
#[cfg(feature = "systemmode")]
pub fn remove_hw_breakpoint(&self, addr: GuestAddr) -> Result<(), Error> {
let ret = unsafe { libafl_qemu_remove_hw_breakpoint(addr.into()) };
let ret = unsafe { libafl_qemu_remove_hw_breakpoint(addr as GuestVirtAddr) };
match ret {
0 => Ok(()),
errno => Err(Error::unsupported(format!(

View File

@ -97,7 +97,7 @@ impl CPU {
attrs.as_mut_ptr(),
);
let mask = Qemu::get_unchecked().target_page_mask();
let offset = vaddr & (mask as GuestVirtAddr);
let offset = (vaddr & (mask as GuestVirtAddr)) as GuestPhysAddr;
#[expect(clippy::cast_sign_loss)]
if paddr == (-1i64 as GuestPhysAddr) {
None
@ -123,7 +123,7 @@ impl CPU {
libafl_qemu_sys::qemu_plugin_mem_rw_QEMU_PLUGIN_MEM_R
},
);
let phwaddr = libafl_qemu_sys::qemu_plugin_get_hwaddr(pminfo, vaddr as GuestVirtAddr);
let phwaddr = libafl_qemu_sys::qemu_plugin_get_hwaddr(pminfo, vaddr as u64);
if phwaddr.is_null() {
None
} else {
@ -438,7 +438,7 @@ impl Iterator for PhysMemoryIter {
);
self.remaining_len -= size_taken;
*vaddr += size_taken as GuestPhysAddr;
*vaddr += size_taken as GuestVirtAddr;
// Now self.addr is host-page aligned
while self.remaining_len > 0 {
@ -458,7 +458,7 @@ impl Iterator for PhysMemoryIter {
size_taken += std::cmp::min(self.remaining_len, phys_page_size);
self.remaining_len -= size_taken;
*vaddr += size_taken as GuestPhysAddr;
*vaddr += size_taken as GuestVirtAddr;
}
// We finished to explore the memory, return the last slice.