Skip to content

Commit

Permalink
Merge branch 'main' into error
Browse files Browse the repository at this point in the history
  • Loading branch information
SWASTIC-7 authored Feb 19, 2025
2 parents 833bb66 + 61568a9 commit 3a44acd
Show file tree
Hide file tree
Showing 75 changed files with 2,674 additions and 1,893 deletions.
6 changes: 6 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## Pull Request Checklist

Please make sure you've completed the following steps before submitting:

- [ ] I have run `./script/fmt_all.sh` to format the code
- [ ] I have run `./script/clippy.sh` and fixed all errors/warnings
1 change: 0 additions & 1 deletion .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ jobs:
needs:
- fuzzers-preflight
strategy:
fail-fast: false
matrix:
os: [ ubuntu-24.04 ]
fuzzer:
Expand Down
64 changes: 44 additions & 20 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

For bugs, feel free to open issues or contact us directly. Thank you for your support. <3

## Pull Request guideline
## Pull Request Guideline

Even though we will gladly assist you in finishing up your PR, try to:

Expand All @@ -14,7 +14,7 @@ Even though we will gladly assist you in finishing up your PR, try to:

Some of the parts in this list may be hard, don't be afraid to open a PR if you cannot fix them by yourself, so we can help.

### Pre-commit hooks
### Pre-commit Hooks

Some of these checks can be performed automatically during commit using [pre-commit](https://pre-commit.com/).
Once the package is installed, simply run `pre-commit install` to enable the hooks, the checks will run automatically before the commit becomes effective.
Expand All @@ -27,7 +27,10 @@ Before making your pull requests, try to see if your code follows these rules.
- `PhantomData` should have the smallest set of types needed. Try not adding `PhantomData` to your struct unless it is really necessary. Also even when you really need `PhantomData`, try to keep the types `T` used in `PhantomData` as smallest as possible
- Wherever possible, trait implementations with lifetime specifiers should use '_ lifetime elision.
- Complex constructors should be replaced with `typed_builder`, or write code in the builder pattern for yourself.
- Remove generic restrictions at the definitions (e.g., we do not need to specify that types impl `Serialize`, `Deserialize`, or `Debug` anymore at the struct definitions). Therefore, try avoiding code like this unless the constraint is really necessary.


## Rules for Generics and Associated Types
1. Remove generic restrictions at the definitions (e.g., we do not need to specify that types impl `Serialize`, `Deserialize`, or `Debug` anymore at the struct definitions). Therefore, try avoiding code like this unless the constraint is really necessary.
```rust
pub struct X<A>
where
Expand All @@ -36,7 +39,7 @@ pub struct X<A>
fn ...
}
```
- Reduce generics to the least restrictive necessary. __Never overspecify the constraints__. There's no automated tool to check the useless constraints, so you have to verify this manually.
2. Reduce generics to the least restrictive necessary. __Never overspecify the constraints__. There's no automated tool to check the useless constraints, so you have to verify this manually.
```rust
pub struct X<A>
where
Expand All @@ -46,8 +49,7 @@ pub struct X<A>
}
```

- Prefer generic to associated types in traits definition as much as possible. They are much easier to use around, and avoid tricky caveats / type repetition in the code. It is also much easier to have unconstrained struct definitions.

3. Prefer generic to associated types in traits definition as much as possible. They are much easier to use around, and avoid tricky caveats / type repetition in the code. It is also much easier to have unconstrained struct definitions.
Try not to write this:
```rust
pub trait X
Expand All @@ -65,7 +67,7 @@ pub trait X<A>
}
```

- Traits which have an associated type (if you have made sure you cannot use a generic instead) should refer to the associated type, not the concrete/generic. In other words, you should only have the associated type when you can define a getter to it. For example, in the following code, you can define a associate type.
4. Traits which have an associated type (if you have made sure you cannot use a generic instead) should refer to the associated type, not the concrete/generic. In other words, you should only have the associated type when you can define a getter to it. For example, in the following code, you can define a associate type.
```rust
pub trait X
{
Expand All @@ -74,17 +76,7 @@ pub trait X
fn a(&self) -> Self::A;
}
```

- __Ideally__ the types used in the arguments of methods in traits should have the same as the types defined on the traits.
```rust
pub trait X<A, B, C> // <- this trait have 3 generics, A, B, and C
{
fn do_stuff(&self, a: A, b: B, c: C); // <- this is good because it uses all A, B, and C.

fn do_other_stuff(&self, a: A, b: B); // <- this is not ideal because it does not have C.
}
```
- Generic naming should be consistent. Do NOT use multiple name for the same generic, it just makes things more confusing. Do:
5. Generic naming should be consistent. Do NOT use multiple name for the same generic, it just makes things more confusing. Do:
```rust
pub struct X<A> {
phantom: PhanomData<A>,
Expand All @@ -100,15 +92,47 @@ pub struct X<A> {

impl<B> X<B> {} // <- Do NOT do that, use A instead of B
```
- Always alphabetically order the type generics. Therefore,
6. __Ideally__ the types used in the arguments of methods in traits should have the same as the types defined on the traits.
```rust
pub trait X<A, B, C> // <- this trait have 3 generics, A, B, and C
{
fn do_stuff(&self, a: A, b: B, c: C); // <- this is good because it uses all A, B, and C.

fn do_other_stuff(&self, a: A, b: B); // <- this is not ideal because it does not have C.
}
```
7. Try to avoid cyclical dependency if possible. Sometimes it is necessary but try to avoid it. For example, The following code is a bad example.
```rust
pub struct X {}
pub struct Y {}

pub trait Fuzzer: Sized {
fn fuzz<EM>(&self, em: &EM)
where
EM: EventManager
{
em.do_stuff(self);
}
}

pub trait EventManager: Sized {
fn do_stuff<Z>(&self, fuzzer: &Z); // <- This function signature should not take fuzzer
}
```
trait `EventManager` should not implement any method that takes fuzzer, any object that could implement `Fuzzer` trait.


## Formatting
1. Always alphabetically order the type generics. Therefore,
```rust
pub struct X<E, EM, OT, S, Z> {}; // <- Generics are alphabetically ordered
```
But not,
```rust
pub struct X<S, OT, Z, EM, E> {}; // <- Generics are not ordered
```
- Similarly, generic bounds in `where` clauses should be alphabetically sorted. Prefer:
2. Similarly, generic bounds in `where` clauses should be alphabetically sorted.
Prefer:
```rust
pub trait FooA {}
pub trait FooB {}
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ document-features = "0.2.10"
fastbloom = { version = "0.8.0", default-features = false }
hashbrown = { version = "0.14.5", default-features = false } # A faster hashmap, nostd compatible
libc = "0.2.159" # For (*nix) libc
libipt = "0.2.0"
libipt = "0.3.0"
log = "0.4.22"
meminterval = "0.4.1"
mimalloc = { version = "0.1.43", default-features = false }
Expand Down
10 changes: 5 additions & 5 deletions fuzzers/binary_only/intel_pt_baby_fuzzer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use libafl::{
corpus::{InMemoryCorpus, OnDiskCorpus},
events::SimpleEventManager,
executors::{
hooks::intel_pt::{IntelPTHook, Section},
hooks::intel_pt::{IntelPTHook, SectionInfo},
inprocess::GenericInProcessExecutor,
ExitKind,
},
Expand Down Expand Up @@ -100,10 +100,10 @@ pub fn main() {
let sections = process_maps
.iter()
.filter_map(|pm| {
if pm.is_exec() && pm.filename().is_some() {
Some(Section {
file_path: pm.filename().unwrap().to_string_lossy().to_string(),
file_offset: pm.offset as u64,
if pm.is_exec() && pm.filename().is_some() && pm.inode != 0 {
Some(SectionInfo {
filename: pm.filename().unwrap().to_string_lossy().to_string(),
offset: pm.offset as u64,
size: pm.size() as u64,
virtual_address: pm.start() as u64,
})
Expand Down
8 changes: 4 additions & 4 deletions fuzzers/binary_only/intel_pt_command_executor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use libafl::{
events::SimpleEventManager,
executors::{
command::{CommandConfigurator, PTraceCommandConfigurator},
hooks::intel_pt::{IntelPTHook, Section},
hooks::intel_pt::{IntelPTHook, SectionInfo},
},
feedbacks::{CrashFeedback, MaxMapFeedback},
fuzzer::{Fuzzer, StdFuzzer},
Expand Down Expand Up @@ -105,9 +105,9 @@ pub fn main() {
.build()
.unwrap();

let sections = [Section {
file_path: target_path.to_string_lossy().to_string(),
file_offset: 0x14000,
let sections = [SectionInfo {
filename: target_path.to_string_lossy().to_string(),
offset: 0x14000,
size: (*code_memory_addresses.end() - *code_memory_addresses.start() + 1) as u64,
virtual_address: *code_memory_addresses.start() as u64,
}];
Expand Down
2 changes: 1 addition & 1 deletion fuzzers/binary_only/qemu_launcher/Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ test_inner: harness build
./tests/injection/test.sh || exit 1

# complie again with simple mgr
cargo build --profile={{PROFILE}} --features="simplemgr,{{ARCH}}" --target-dir={{ TARGET_DIR }}
cargo build --profile={{PROFILE}} --features="simplemgr,{{ARCH}}" --target-dir={{ TARGET_DIR }} || exit 1
./tests/qasan/test.sh || exit 1

[unix]
Expand Down
27 changes: 20 additions & 7 deletions fuzzers/binary_only/qemu_launcher/src/instance.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::fmt::Debug;
use std::{fs, marker::PhantomData, ops::Range, path::PathBuf, process};
use std::{fs, marker::PhantomData, ops::Range, process};

#[cfg(feature = "simplemgr")]
use libafl::events::SimpleEventManager;
Expand All @@ -9,7 +9,7 @@ use libafl::{
corpus::{Corpus, HasCurrentCorpusId, InMemoryOnDiskCorpus, OnDiskCorpus},
events::{ClientDescription, EventRestarter},
executors::{Executor, ExitKind, ShadowExecutor},
feedback_or, feedback_or_fast,
feedback_and_fast, feedback_or, feedback_or_fast,
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
fuzzer::{Evaluator, Fuzzer, StdFuzzer},
inputs::{BytesInput, Input},
Expand Down Expand Up @@ -185,15 +185,22 @@ impl<M: Monitor> Instance<'_, M> {
// Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time");

let map_feedback = MaxMapFeedback::new(&edges_observer);
let map_feedback = MaxMapFeedback::with_name("map_feedback", &edges_observer);
let map_objective = MaxMapFeedback::with_name("map_objective", &edges_observer);

let calibration = CalibrationStage::new(&map_feedback);
let calibration_cmplog = CalibrationStage::new(&map_feedback);

let stats_stage = IfStage::new(
|_, _, _, _| Ok(self.options.tui),
tuple_list!(AflStatsStage::builder()
.map_observer(&edges_observer)
.stats_file(PathBuf::from("stats.txt"))
.build()?),
);
let stats_stage_cmplog = IfStage::new(
|_, _, _, _| Ok(self.options.tui),
tuple_list!(AflStatsStage::builder()
.map_observer(&edges_observer)
.build()?),
);

Expand All @@ -207,7 +214,10 @@ impl<M: Monitor> Instance<'_, M> {
);

// A feedback to choose if an input is a solution or not
let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new());
let mut objective = feedback_and_fast!(
feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()),
map_objective
);

// // If not restarting, create a State from scratch
let mut state = match state {
Expand Down Expand Up @@ -324,7 +334,8 @@ impl<M: Monitor> Instance<'_, M> {
StdPowerMutationalStage::new(mutator);

// The order of the stages matter!
let mut stages = tuple_list!(calibration, tracing, i2s, power, stats_stage);
let mut stages =
tuple_list!(calibration_cmplog, tracing, i2s, power, stats_stage_cmplog);

self.fuzz(
&mut state,
Expand All @@ -348,7 +359,9 @@ impl<M: Monitor> Instance<'_, M> {

// Setup an havoc mutator with a mutational stage
let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations()));
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
let power: StdPowerMutationalStage<_, _, BytesInput, _, _, _> =
StdPowerMutationalStage::new(mutator);
let mut stages = tuple_list!(calibration, power, stats_stage);

self.fuzz(
&mut state,
Expand Down
2 changes: 1 addition & 1 deletion fuzzers/forkserver/libafl-fuzz/Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ build_libafl_fuzz_fuzzbench:

test_instr: build_afl build_libafl_fuzz
#!/bin/bash
AFL_PATH={{AFL_DIR}} {{AFL_CC_PATH}} ./test/test-instr.c -o ./test/out-instr
AFL_PATH={{AFL_DIR}} {{AFL_CC_PATH}} -O0 ./test/test-instr.c -o ./test/out-instr

export LIBAFL_DEBUG_OUTPUT=1
export AFL_CORES=0
Expand Down
5 changes: 3 additions & 2 deletions fuzzers/forkserver/libafl-fuzz/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,15 @@ struct Opt {
#[arg(short = 't', default_value_t = 1000)]
hang_timeout: u64,

#[arg(short = 'd')]
debug_child: bool,

// Environment Variables
#[clap(skip)]
bench_just_one: bool,
#[clap(skip)]
bench_until_crash: bool,

#[clap(skip)]
debug_child: bool,
#[clap(skip)]
is_persistent: bool,
#[clap(skip)]
Expand Down
22 changes: 14 additions & 8 deletions fuzzers/forkserver/libafl-fuzz/src/stages/mutational_stage.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
use std::{borrow::Cow, marker::PhantomData};

use libafl::{
stages::{MutationalStage, Stage},
stages::{MutationalStage, Restartable, Stage},
Error,
};
use libafl_bolts::Named;

#[derive(Debug)]
pub enum SupportedMutationalStages<SM, P> {
pub enum SupportedMutationalStages<P, SM> {
StdMutational(SM, PhantomData<P>),
PowerMutational(P, PhantomData<SM>),
}

impl<S, SM, P> MutationalStage<S> for SupportedMutationalStages<SM, P>
impl<P, S, SM> MutationalStage<S> for SupportedMutationalStages<P, SM>
where
SM: MutationalStage<S>,
P: MutationalStage<S, Mutator = SM::Mutator>,
SM: MutationalStage<S>,
{
type Mutator = SM::Mutator;
/// The mutator, added to this stage
Expand Down Expand Up @@ -44,10 +44,10 @@ where
}
}

impl<SM, P> Named for SupportedMutationalStages<SM, P>
impl<P, SM> Named for SupportedMutationalStages<P, SM>
where
SM: Named,
P: Named,
SM: Named,
{
fn name(&self) -> &Cow<'static, str> {
match self {
Expand All @@ -57,10 +57,10 @@ where
}
}

impl<E, EM, S, SM, P, Z> Stage<E, EM, S, Z> for SupportedMutationalStages<SM, P>
impl<E, EM, P, S, SM, Z> Stage<E, EM, S, Z> for SupportedMutationalStages<P, SM>
where
SM: Stage<E, EM, S, Z>,
P: Stage<E, EM, S, Z>,
SM: Stage<E, EM, S, Z>,
{
#[inline]
fn perform(
Expand All @@ -75,7 +75,13 @@ where
Self::PowerMutational(p, _) => p.perform(fuzzer, executor, state, manager),
}
}
}

impl<P, S, SM> Restartable<S> for SupportedMutationalStages<P, SM>
where
P: Restartable<S>,
SM: Restartable<S>,
{
fn should_restart(&mut self, state: &mut S) -> Result<bool, Error> {
match self {
Self::StdMutational(m, _) => m.should_restart(state),
Expand Down
2 changes: 1 addition & 1 deletion fuzzers/full_system/unicorn/Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ test_single arch="arm":
#!/bin/bash
echo "Testing {{arch}}"

RUST_LOG="debug" timeout 10s {{FUZZER}} {{arch}} 2>&1 | tee fuzz_stdout.log || true
RUST_LOG="debug" timeout 30s {{FUZZER}} {{arch}} 2>&1 | tee fuzz_stdout.log || true
if grep -qa "objectives: 1" fuzz_stdout.log; then
echo "Fuzzer is working"
else
Expand Down
Loading

0 comments on commit 3a44acd

Please sign in to comment.