test/fuzzer: fix AFL harness input handling and restore it to a compiling state - #3607
Open
shotintoeternity wants to merge 2 commits into
Open
Conversation
…ling state The harness has not compiled since 5d39890 (merged 2024-08-27) renamed Transformation::evaluate to transform(std::string&, const Transaction*) and removed Action::evaluate(const std::string&, Transaction*). 4df297b (merged 2024-10-07) later changed the fourth parameter of Operator::evaluate from std::shared_ptr<RuleMessage> to RuleMessage&, breaking op_test as well. Neither change touched test/fuzzer/, and --enable-afl-fuzz defaults to false (configure.ac:284), so no CI job surfaced the breakage. A syntax check of current v3/master reports 38 errors in the file. Independently of that, std::string(read_bytes, 128) selected the fill constructor basic_string(size_type count, CharT ch), so the harness ran against read_bytes copies of the character 128 rather than the input AFL supplied. buf was never read from. The compiler has been reporting this as a -Wconstant-conversion warning since the harness was written in c2d9a15. - Build the input string from buf, and skip iterations where read returns nothing. - Update op_test to the current 3-argument Operator::evaluate. - Port the 37 generated transformation calls to Transformation::transform, constructing the classes directly rather than via Transformation::instantiate, whose t:-prefixed matching does not accept class-cased names and would silently yield base-class no-ops. - Add a single-shot __AFL_LOOP fallback so the harness compiles without afl++ installed, and terminates rather than spinning on empty input. Original find and the input-handling fix by @Easton97-Jens in owasp-modsecurity#3556.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe AFL harness adds a single-iteration fallback, validates read results, uses the actual input length, and evaluates transformations through a transaction-aware helper with isolated input copies. ChangesAFL harness execution
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
The generator commands recorded in the harness comments contained src/actions/transformations/*.h and similar, so a "/*" sat inside a block comment and reads as a nested comment opener. SonarQube reports it as cpp:S1103. Quote the glob when handing it to find, and pass the directory straight to grep -R, which needs no glob at all. Both rewritten forms produce output byte-identical to the originals, so the comments still document exactly what generated the include list and the tfn_test/op_test calls. Comment-only change. The harness behavior is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



what
Restores
test/fuzzer/afl_fuzzer.ccto a compiling state and makes it fuzz theactual input it is given.
bufinstead of the fill constructor, and skipsiterations where
readreturns nothing.op_testto the current 3-argumentOperator::evaluate.Transformation::transform(std::string&, const Transaction*).__AFL_LOOPfallback so the harness compiles without afl++installed.
One file, no build-system or CI changes.
why
The harness does not compile. On current
v3/master:37 are the generated transformation lines and 1 is
op_test.__AFL_LOOPisdefined on the command line above because
afl-clang-fastsupplies it, so it isnot one of the errors.
Two API changes caused this, neither of which touched the harness:
5d398907(merged 2024-08-27) renamedTransformation::evaluatetotransform(std::string &value, const Transaction *trans)and removedAction::evaluate(const std::string&, Transaction*).4df297b5(merged 2024-10-07) changed the fourth parameter ofOperator::evaluatefromstd::shared_ptr<RuleMessage>toRuleMessage&, sonullptrno longer binds.Syntax-checking
5d398907^gives 0 errors, so the harness last built in August2024. It is gated behind
--enable-afl-fuzz, which defaults to false(
configure.ac:284) and only then generatestest/fuzzer/Makefile(
configure.ac:386), so no CI job surfaces the breakage.The input was never the fuzzer's input. Independently of the above,
std::string(read_bytes, 128)selects the fill constructorbasic_string(size_type count, CharT ch), givingread_bytescopies of thecharacter
128. Overload resolution is not ambiguous, which is likely why itsurvived: the pointer-and-length constructor is not viable because
ssize_tdoesnot convert to
const char*, and the iterator-pair constructor is not viablebecause deduction conflicts.
bufappears three times in the file, in itsdeclaration, its
memsetand itsread, and is never read from. The compiler hasbeen saying so all along:
git log -L145,145:test/fuzzer/afl_fuzzer.ccreturns a single commit,c2d9a153("Adds support to afl fuzzer in the build system", 2015-12-22), so the line is
unchanged since the harness was written.
The practical effect is that the harness's input domain was a run of
0x80byteswhose only attacker-controlled property was its length, 0 to 128, which is 129
distinct inputs.
t:hexDecodenever saw a hex digit,Base64Decodenever sawbase64,
DetectSQLiandDetectXSSnever saw a quote or an angle bracket.on the transformation calls
The 37 transformation lines are ported to a helper that mirrors the existing
op_test:so each generated line becomes
tfn_test<Base64Decode>("Base64Decode", s, t);.This constructs the classes directly, as the current file already does, rather than
routing through
Transformation::instantiate. That is deliberate.instantiatematches withThe compare starts at offset 2 because it expects the rule-language spelling with
the
t:prefix, as int:base64Decode. Class-cased names match nothing, fallthrough every branch, and reach the final
return new Transformation(a), which isthe base class, whose
transform()returnsfalsewithout touching the value.Passing the 37 class names to
instantiateand checking the dynamic type:Direct construction sidesteps the prefix convention entirely and keeps the name
list compile-checked, so a wrong name is a build error rather than a silent no-op.
on the __AFL_LOOP fallback
afl-clang-fastdefines__AFL_LOOP. Without it the file does not compile, whichis part of why this rot went unnoticed for two years. The fallback here is
single-shot rather than a literal
1, so a non-AFL build reads stdin once andexits instead of spinning at EOF against the new
read_bytes <= 0guard.verification
Built
libmodsecurityfrom this branch and compiled the harness against it with aplain compiler:
-Wcommentones from the/*sequences inside the "generated by" block comments, which are untouched here.
credit
The input-handling bug and the
op_testsignature fix are @Easton97-Jens's find,from #3556. This PR carries the
afl_fuzzer.ccportion of that work on its own, attheir suggestion, so it can be reviewed without the CI and workflow changes bundled
there. The CI additions in #3556 are unaffected by this and remain for separate
discussion.
Summary by CodeRabbit