`ExitKind::Ok` exposing the result of `libfuzzer_test_one_input`
Currently, libfuzzer_test_one_input returns an i32 that is discarded when turning into ExitKind::Ok, whereas the value could potentially signal interestingness from the harness leveraged by domain-specific fuzzers. I suppose ExitKind is part of the public API so it wouldn't be possible to change it after this point, but perhaps an ExitKind::Value(i32) would come in handy?
ExitKind::Value would be interesting, but it would need to be generic... I can see use cases including things like differential fuzzers where we would care about other types of values. Implementing this is nontrivial, though.
The LLVMFuzzerTestOneInput function has well-defined return values, though. We have functionality for processing this more precisely if needed (note that -2 is LibAFL specific behavior).
The ability to have a generic result would be very nice but I guess it wouldn't be possible given the fact that the output type is capped by size to be an integer, so the return type must have a cardinality of 2^64, that is if we don't coerce it to return a pointer instead?
I hadn't seen the -2 case, that is a bit unfortunate I guess, but is it part of the public API? The harness wrap is only pub(crate) so it seems possible to change? What I can think of is to change the return type of https://github.com/AFLplusplus/LibAFL/blob/main/crates/libafl_libfuzzer/runtime/src/harness_wrap.cpp#L3 to be a tagged union that returns HarnessExitKind::Crash on the failure case instead of -2 and return HarnessExitKind::Ok on the success case, which would be constrained within the bounds of the library without leaking outside?
The LibFuzzer definition seems to me to be a fuzzer specific interpretation of the result value, so the default behavior could be to use 0 and 1 as keep/discard but it shouldn't be forced onto all potential fuzzers written using LibAFL?
The ability to have a generic result would be very nice but I guess it wouldn't be possible given the fact that the output type is capped by size to be an integer, so the return type must have a cardinality of 2^64, that is if we don't coerce it to return a pointer instead?
We don't just fuzz libFuzzer targets :) Sometimes we might fuzz something with a different harness type, and want to have some structured return value.
I hadn't seen the -2 case
Don't worry about that, that just means "crash". We wouldn't export that to user.
it shouldn't be forced onto all potential fuzzers written using LibAFL?
It isn't; that's the libFuzzer compatibility code. What I'm suggesting is that, if we do want to support value collection from the target (outside of how we already do so with observers), it would need to be generic s.t. people can return whatever they like from their harness.
Ah I see. I initially misunderstood the concern, sorry.
So, just to summarise: this issue is a "nice to have" for a generic value present in the ExitKind::Ok and maybe a second generic value present in the ExitKind::Crash (vis-a-vis Result).
Yes, that is correct I think. As an possible alternative to avoid breaking existing harnesses, having a new variant ExitKind::Value(T) could also be useful.