LibAFL icon indicating copy to clipboard operation
LibAFL copied to clipboard

Sample implementation of tracking enforcement

Open addisoncrump opened this issue 2 years ago • 6 comments

This comes from a suggestion in the discord to type-enforce whether indices/novelties should be tracked.

It turns out that you cannot infer whether it needs to be or not based purely on usage. This is a limitation of Rust -- I have tried many, many different ways of doing this now with no avail (pure type encoding, GAT encoding, associated constant encoding, even this nightmare-fuel syntax), but we can encode the metadata -- it just has to be manually performed by the user.

I added some docs and only modified MapFeedback and MinimizerScheduler for the sake of demonstration. Play around with libfuzzer_stb_image to see how the compiler output feels and such when intentionally disabling index tracking.

addisoncrump avatar Feb 27 '24 02:02 addisoncrump

cc @sadeli413 as you were the one who mentioned this

addisoncrump avatar Feb 27 '24 02:02 addisoncrump

I've improved this a bit s.t. it dumps a helpful compiler message if you've done it wrong. image

addisoncrump avatar Feb 28 '24 13:02 addisoncrump

I've improved this further by integrating with the existing pattern: image

addisoncrump avatar Feb 28 '24 14:02 addisoncrump

Is this something we want to pursue? I'm happy to make the remaining changes, but it's a lot of work and I don't want to get started without a preliminary review.

addisoncrump avatar Feb 28 '24 14:02 addisoncrump

Unless there are any complaints I'll start implementing this March 1st.

addisoncrump avatar Feb 28 '24 15:02 addisoncrump

@domenukk So, now the only new onus on implementors of MapObserver is to impl AsRef<Self>. Making things that accept MapObservers is now a little more complicated (because it needs to accept an AsRef<O> where O is the map observer).

The reason is that now, there's a wrapper type ("ExplicitTracking") which just wraps the map observer and forwards its observer implementation. But we can impl TrackingHinted for all map observers now with a default without them needing to do any type-fu at the definition and ExplicitTracking carries the tracking information if it needs to be specified. This works because now A: AsRef<O> can now be A = O when no tracking information is specified => we fall back to the "no tracking default". If we had specialisation, we could drop the need for this AsRef nonsense and just impl MapObserver for ExplicitTracking, but sadly we need it because we define TrackingHinted over all MapObservers and we end up with a conflict.

addisoncrump avatar Feb 29 '24 16:02 addisoncrump

There is a difference between formatting in stable and nightly... not optimal

addisoncrump avatar Mar 06 '24 16:03 addisoncrump

See: image

It seems we are inconsistently using rustfmt somehow. I'll fix this later.

addisoncrump avatar Mar 06 '24 16:03 addisoncrump

I think we can always use nightly fmt then

domenukk avatar Mar 08 '24 23:03 domenukk

Okay, I forced the formatter version and for some reason it continues to format differently.

addisoncrump avatar Mar 11 '24 12:03 addisoncrump

[*] Checking fmt for ./fuzzers/libfuzzer_stb_image_concolic/fuzzer
Warning: can't set `imports_granularity = Crate`, unstable features are only available in nightly channel.
Warning: can't set `group_imports = StdExternalCrate`, unstable features are only available in nightly channel.
Warning: can't set `imports_granularity = Crate`, unstable features are only available in nightly channel.
Warning: can't set `group_imports = StdExternalCrate`, unstable features are only available in nightly channel.
Diff in /home/runner/work/LibAFL/LibAFL/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs at line 3:
Warning: can't set `imports_granularity = Crate`, unstable features are only available in nightly channel.
Warning: can't set `group_imports = StdExternalCrate`, unstable features are only available in nightly channel.

-> It's not using nightly here as you can see in the Warnings. We should probably fmt everything with nightly for the time being

domenukk avatar Mar 13 '24 00:03 domenukk

Rebased, that was a doozy.

addisoncrump avatar Mar 13 '24 12:03 addisoncrump

Oooh sorry I had already merged main into this guy locally, but forgot to push 🙈

domenukk avatar Mar 13 '24 12:03 domenukk

Needs more .scripts/fmt-all.sh

domenukk avatar Mar 15 '24 16:03 domenukk

Oooh sorry I had already merged main into this guy locally, but forgot to push 🙈

Please don't use merge on my PRs! I prefer rebase, and mixing them can delete intermediary commits.

addisoncrump avatar Mar 15 '24 16:03 addisoncrump

Needs more .scripts/fmt-all.sh

This does nothing on my system, and I am using nightly.

addisoncrump avatar Mar 15 '24 16:03 addisoncrump

What's the status?

Oooh sorry I had already merged main into this guy locally, but forgot to push 🙈

Please don't use merge on my PRs! I prefer rebase, and mixing them can delete intermediary commits.

Merge is way easier to handle btw and we're squashing this anyway into main - I recommend using merge ;)

domenukk avatar Mar 20 '24 12:03 domenukk

It's easier to handle, until someone does a partial revert :slightly_smiling_face:

I just haven't had time the past few days to work on this, and I'm entirely unable to reproduce what's happening on CI locally.

addisoncrump avatar Mar 20 '24 14:03 addisoncrump

Okay, what eventually fixed it was to simply recursively touch all the files. Don't know why this worked, but it did.

addisoncrump avatar Mar 28 '24 14:03 addisoncrump

Any argument to me just merging this when I rebase + finally fix the clippy/fmt issues?

addisoncrump avatar Mar 30 '24 16:03 addisoncrump

Any argument to me just merging this when I rebase + finally fix the clippy/fmt issues?

Please do! :)

domenukk avatar Apr 02 '24 08:04 domenukk

(After renaming TrackingHinted as discussed)

domenukk avatar Apr 02 '24 08:04 domenukk

Rename and then merge?

domenukk avatar Apr 09 '24 23:04 domenukk

Rebased

domenukk avatar Apr 11 '24 21:04 domenukk

Sorted generics

domenukk avatar Apr 11 '24 22:04 domenukk

@addisoncrump I would rename the generic to C or CT (Can Track) - A doesn't really mean anything?

domenukk avatar Apr 11 '24 23:04 domenukk

Rebasing is way more work than merging, you have to touch the same line multiple times... Will merge again in the future

domenukk avatar Apr 12 '24 12:04 domenukk

It seems that this change broke fuzzers/forkserver_libafl_cc. It builds, but the run fails. It first fails because the map size is smaller then the default. If I fix this, it fails because it does not find the observer: if let Some(dynamic_map_size) = executor.coverage_map_size() { executor .observers_mut() .match_name_mut::<HitcountsMapObserver<StdMapObserver<'_, u8, false>>>("shared_mem") .unwrap() .truncate(dynamic_map_size); } When I print the type_name of the observer, it tells me it is ExplicitTracking<HitcountsMapObserver... and not just <HitcountsMapObserver...

mkravchik avatar Apr 17 '24 09:04 mkravchik