smite-ir-mutator: drop 5% fresh-generation branch in fuzz - #154
smite-ir-mutator: drop 5% fresh-generation branch in fuzz#154erickcestari wants to merge 1 commit into
Conversation
AFL's corpus scheduler already handles seed rotation, and gen-insert supplies generator-driven novelty without discarding the seed. Fresh generation now only serves as a decode/empty-input fallback.
|
I don't think I can infer from your comment that this behaviour is supposed to be covered up by AFL++'s corpus scheduler, but that raises the question of why we did not rely on it in the first place? I believe it's because (again) the scheduler cannot generate new seeds, only rotate between the existing. The fresh-generation branch encompasses a "drastically switch the protocol mechanism that we're testing right now" component that isn't fully captured by the |
The fresh-generation branch was first added because we didn't have any mutator that adds new program into the input. So we needed a way to generate a valid program somewhere.
It rotate seeds, if it's not rotating what is the propose of having coverage-guided feedback to save inputs if the fuzzer will never use those? I've run smite with logs enabled and after initial stage it starts using new seeds.
Yes, I agree. I'll provide the statistical data as soon as possible. I'll start from an empty seed and use #141 as the base, since that enables deeper fuzzing. |
|
Thanks for running the evaluation experiments, @erickcestari! Here's the CSV data you provided as a Markdown table:
The A12 statistic is ~0.5 and the p-value for is >> 0.05 for both final coverage and AUC. This points to the fact that the configurations are identical in terms of coverage-capabilities. We might be able to get a stronger result if we increase the timeout/trial count, or change the target. What is interesting here is the fact that the IQR spread of the experimental config (in terms of both final coverage and AUC) is significantly higher than the baseline. I understand why the Asked an LLM for an opinion and this is what I got:
which seems reasonable. I think an experiment with a a longer timeout is worth running here. Over a long enough timeline, the experimental config might eventually stall out entirely without fresh inputs, while the baseline continues to slowly discover new paths. |
|
This result matches my intuition. The 5% fresh-generation branch acts like a fixed seed corpus, helping to reduce variance in fuzzing. It also provides a bit of a weight pulling the fuzzer down to smaller programs. Without that branch, the main way to exercise new flows is to insert an entire generator sequence into an existing program, thus creating a larger combined program. In general, larger inputs reduce fuzzing efficiency, which is the whole point of AFL++'s trim operation. BTW, I've noticed for many large programs, execution actually stops early on in the program. I think that's a hint that a truncating minimizer would be quite helpful for reducing average input size. |
Truncating as in deleting parts of the program? Wouldn't that break the coverage-preserving invariant for minimizers? Also, I'm curious about how you observed program execution stopping early, maybe there's a different way to mitigate it if we can pinpoint the cause. |
No, it's fine if coverage changes sometimes -- AFL++ automatically filters such changes out. So we can have minimizers that do drastic things like delete half the program, and AFL++ will still do the right thing. Suppose only the first 10 lines of a program are ever executed. A truncation minimizer would be very effective since we should be able to delete anything after the first 10 lines and the coverage will be unchanged.
There are many ways for execution to stop early. But by far the most common is receiving an |
Oh okay, I think I misunderstood what you said initially. Execution stops on early in many large programs because we hit one of these expected error paths early on, making the rest of the program no-op. This is expected behavior and not something that happens because the program is "too large". The truncating minimizer makes sense within this context then. |
|
Here's an 8-trial 15h run against LDK. Configuration A (Baseline):
Target: ldkMedian Coverage Over Time
Distribution Comparisons
|
Huh, turned out to be less favorable towards baseline than I expected (in terms of final coverage). |
|
I've ran a 20-trial 12h run against LDK. But since my machine is slower than the morehouse the results aren't so good. I'll try running a final and longer one to get a a better overview. Configuration A (Baseline): baseline 1. Summary Statistics
Target: ldkMedian Coverage Over Time
Distribution Comparisons
|
Right. At this point, I don't think running more counts of short trials will give us a different picture. A smaller count of longer trials (~24 hours) is probably our best bet at that. |









AFL's corpus scheduler already handles seed rotation, and
gen-insertsupplies generator-driven novelty without discarding the seed. Fresh generation now only serves as a decode/empty-input fallback.We don't need the fresh-generation branch anymore, since we already have
gen-insertthat inserts new program in an existing one.