* autofix
* you're just asking for a clamping
* autofmt on linux
* fix nits
* change back nit
* unfixing as u64 for GuestAddr
* fix
* ignoring clippy for GuestAddress
* Adding fork feature passing from libafl_qemu to libafl crate
* Removing patches from a different PR
* Adding fork as a default feature for libafl_qemu
* Removing rand_trait feature from libafl_qemu
* Changes to build QEMU out-of-tree so that we don't need to clone the repo for each feature combination we build
* Add be support to libafl_qemu
* More config tweaks
Co-authored-by: Your Name <you@example.com>
* Adding qemu_arm_launcher crate
* Trying to fix qemu arm usermode
* Cargo fmt
* Adding CROSS_CC env
* Remove hardcoded arm-linux-gnueabi-gcc and replace by CROSS_CC
* Adding arm-linux-gnueabi-gcc to github workflows for ubuntu
* Fixing typo in apt install package
* Resetting LR after each fuzzing emulation
* Cargo fmt after merge conflict
* Using GuestAddr
* Compiling, running and running with artificial crash detection
* Adding dependencies for github workflow to cross compile for arm
* Fixing github workflow for ubuntu fuzzer
* arm-linux-binutils for mac in github workflows
* Qemu does not work for mac, no need to compile qemu_arm_launcher harness for it
Guest addresses now represented by correct sized integers.
Previously u64 was used to represent guest addresses. This is great for
64-bit targets, but clunky for other architectures. This introduces a
GuestAddr type alias that is defined based on the selected emulation
architecture.
Note: This changes only the user-facing Rust interface. Before
traversing the FFI boundary, all GuestAddrs are sized back to u64.
Another Note: Guest addresses _from_ the FFI boundary are completely
trusted. Values that are too large are truncated to fit into a GuestAddr
using the `as GuestAddr` cast. This may not be ideal, as errors could be
masked. If desired and the performance is ok, a non-breaking update
could change all `as` casts to `.try_into().unwrap()` so that critical
failures in FFI are always checked.
Methods read_mem and write_mem now operate on &[u8], not &[T]
The generic T slice interface was prone to various footguns:
* i32 is the default Rust integer type, but buffers are often expected
to hold u8. This means the following code writes 16 bytes to the
guest, not 4:
let buf = [0; 4];
emu.write_mem(addr, &buf);
* If a buffer of 16-bit or larger integers (&[u64] for example) is
needed to read/write, the user will need to consider host/guest
endianness. The byte array methods in std are a good, explicit
alternative.
Perhaps libafl_qemu could expose/define "to/from guest endianness"
helper functions or extension traits using the established cfg flags,
so that guest endianness is always right by default.
* emu::read_mem causes insta-UB if a user did something like:
let mut my_bool = false;
emu.read_mem(addr, &mut my_bool);
It's less surprising for users to just operate on plain-ol' bytes,
which they can explicitly transmute if they wish.
Specifically for Has{Rand,Corpus,Solutions,FeedbackStates}
The Has* family of traits offer getters and get-mut-ers. The previous
implementation had a fully generic return type:
trait HasX<X: TraitX> {
get_x(&self) -> &Self::X;
get_mut_x(&mut self) -> &mut Self::X;
}
meaning a single type could implement both `HasRand<Romu>` and
`HasRand<XorShift>`. The advantage of having multiple implementations is
not clear at this time, so it vastly simplifies the trait (and its
impls) to bring the return type in the body as an associated type:
trait HasX {
type X: TraitX;
get_x(&self) -> &Self::X;
get_mut_x(&mut self) -> &mut Self::X;
}
This comes with the limitation that any type that impls these traits can
only do so once, choosing only one associated type.
* HasRand's only generic parameter (Rand) is now an associated type
* HasCorpus and HasSolutions are now only generic over the Input type
they store
* HasFeedbackStates generic parameter now associated type