Skip to content

Commit 277cf93

Browse files
committed
Preliminary support for libfuzzer
1 parent 37e7ad0 commit 277cf93

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1416
-447
lines changed

.github/workflows/ci.yml

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,52 @@ jobs:
101101
cargo clean && cargo +nightly udeps --features=test-fuzz/auto_concretize --all-targets
102102
103103
test:
104-
runs-on: ubuntu-latest
105-
106104
strategy:
107105
fail-fast: false
108106
matrix:
109-
serde_format: [bincode, cbor, cbor4ii]
110-
toolchain: [stable, nightly]
107+
include:
108+
- fuzzer: aflplusplus
109+
environment: ubuntu-latest
110+
serde_format: bincode
111+
toolchain: stable
112+
- fuzzer: aflplusplus
113+
environment: macos-latest
114+
serde_format: bincode
115+
toolchain: nightly
116+
- fuzzer: aflplusplus-persistent
117+
environment: ubuntu-latest
118+
serde_format: cbor
119+
toolchain: stable
120+
- fuzzer: libfuzzer
121+
environment: ubuntu-latest
122+
serde_format: cbor
123+
toolchain: nightly
124+
- fuzzer: libfuzzer
125+
environment: macos-latest
126+
serde_format: cbor4ii
127+
toolchain: stable
128+
- fuzzer: aflplusplus
129+
environment: ubuntu-latest
130+
serde_format: cbor4ii
131+
toolchain: nightly
132+
- fuzzer: aflplusplus
133+
environment: macos-latest
134+
serde_format: bincode
135+
toolchain: stable
136+
- fuzzer: aflplusplus-persistent
137+
environment: ubuntu-latest
138+
serde_format: bincode
139+
toolchain: nightly
140+
- fuzzer: libfuzzer
141+
environment: ubuntu-latest
142+
serde_format: cbor
143+
toolchain: stable
144+
- fuzzer: libfuzzer
145+
environment: macos-latest
146+
serde_format: cbor
147+
toolchain: nightly
148+
149+
runs-on: ${{ matrix.environment }}
111150

112151
steps:
113152
- uses: actions/checkout@v3
@@ -118,11 +157,17 @@ jobs:
118157
run: rustup default ${{ matrix.toolchain }}
119158

120159
- name: Install llvm
160+
if: ${{ matrix.environment == 'ubuntu-latest' }}
121161
run: sudo apt-get install llvm
122162

123163
# smoelius: The Substrate tests require `protoc`.
124164
- name: Install protoc
125-
run: sudo apt-get install protobuf-compiler
165+
run: |
166+
if [[ ${{ matrix.environment }} = 'ubuntu-latest' ]]; then
167+
sudo apt-get install protobuf-compiler
168+
else
169+
brew install protobuf
170+
fi
126171
127172
- name: Install afl
128173
run: cargo install afl
@@ -132,6 +177,11 @@ jobs:
132177
test "$(ls ~/.local/share/afl.rs | wc -l)" -eq 1
133178
test "$(ls ~/.local/share/afl.rs/rustc-* | wc -l)" -eq 1
134179
sudo "$HOME"/.local/share/afl.rs/rustc-*/afl.rs-*/afl/bin/afl-system-config
180+
if [[ ${{ matrix.environment }} = 'macos-latest' ]]; then
181+
SL=/System/Library; PL=com.apple.ReportCrash
182+
launchctl unload -w ${SL}/LaunchAgents/${PL}.plist
183+
sudo launchctl unload -w ${SL}/LaunchDaemons/${PL}.Root.plist
184+
fi
135185
136186
# smoelius: The wasm32 target is needed for some Substrate tests, regardless of the toolchain
137187
# used to build test-fuzz.
@@ -144,7 +194,7 @@ jobs:
144194
run: |
145195
AUTO_CONCRETIZE=
146196
SHUFFLE=
147-
if [[ ${{ matrix.toolchain }} = nightly ]]; then
197+
if [[ ${{ matrix.toolchain }} = 'nightly' ]]; then
148198
AUTO_CONCRETIZE='--features=test-fuzz/auto_concretize'
149199
SHUFFLE='-Z unstable-options --shuffle --test-threads=1'
150200
fi
@@ -158,6 +208,7 @@ jobs:
158208
env:
159209
RUST_BACKTRACE: 1
160210
RUST_LOG: warn
211+
TEST_FUZZ_FUZZER: ${{ matrix.fuzzer }}
161212

162213
test-uninstalled-cargo-afl:
163214
runs-on: ubuntu-latest
@@ -172,13 +223,14 @@ jobs:
172223
run: |
173224
OUTPUT="$(cargo run -p cargo-test-fuzz -- test-fuzz -p test-fuzz-examples --no-run 2>&1 1>/dev/null || true)"
174225
echo "$OUTPUT"
175-
echo "$OUTPUT" | grep '^Error: Could not determine `cargo-afl` version. Is it installed? Try `cargo install afl`.$'
226+
echo "$OUTPUT" | grep 'Could not determine `cargo-afl` version. Is it installed? Try `cargo install afl`.'
176227
177228
test-incompatible-cargo-afl:
178229
runs-on: ubuntu-latest
179230

180231
env:
181232
RUSTUP_TOOLCHAIN: nightly
233+
TEST_FUZZ_FUZZER: aflplusplus-persistent
182234

183235
steps:
184236
- uses: actions/checkout@v3
@@ -200,6 +252,7 @@ jobs:
200252

201253
env:
202254
RUSTUP_TOOLCHAIN: nightly
255+
TEST_FUZZ_FUZZER: aflplusplus-persistent
203256

204257
steps:
205258
- uses: actions/checkout@v3

README.md

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -248,50 +248,52 @@ The `cargo test-fuzz` command is used to interact with fuzz targets, and to mani
248248
#### Options
249249

250250
```
251-
--backtrace Display backtraces
252-
--consolidate Move one target's crashes, hangs, and work queue to its corpus; to
253-
consolidate all targets, use --consolidate-all
254-
--display <OBJECT> Display concretizations, corpus, crashes, `impl` concretizations,
255-
hangs, or work queue. By default, corpus uses an uninstrumented fuzz
256-
target; the others use an instrumented fuzz target. To display the
257-
corpus with instrumentation, use --display corpus-instrumented.
258-
[possible values: concretizations, corpus, corpus-instrumented,
259-
crashes, hangs, impl-concretizations, queue]
260-
--exact Target name is an exact name rather than a substring
261-
--exit-code Exit with 0 if the time limit was reached, 1 for other programmatic
262-
aborts, and 2 if an error occurred; implies --no-ui, does not imply
263-
--run-until-crash or -- -V <SECONDS>
264-
--features <FEATURES> Space or comma separated list of features to activate
265-
--list List fuzz targets
266-
--manifest-path <PATH> Path to Cargo.toml
267-
--no-default-features Do not activate the `default` feature
268-
--no-instrumentation Compile without instrumentation (for testing build process)
269-
--no-run Compile, but don't fuzz
270-
--no-ui Disable user interface
271-
-p, --package <PACKAGE> Package containing fuzz target
272-
--persistent Enable persistent mode fuzzing
273-
--pretty-print Pretty-print debug output when displaying/replaying
274-
--replay <OBJECT> Replay corpus, crashes, hangs, or work queue. By default, corpus uses
275-
an uninstrumented fuzz target; the others use an instrumented fuzz
276-
target. To replay the corpus with instrumentation, use --replay
277-
corpus-instrumented. [possible values: concretizations, corpus,
278-
corpus-instrumented, crashes, hangs, impl-concretizations, queue]
279-
--reset Clear fuzzing data for one target, but leave corpus intact; to reset
280-
all targets, use --reset-all
281-
--resume Resume target's last fuzzing session
282-
--run-until-crash Stop fuzzing once a crash is found
283-
--test <NAME> Integration test containing fuzz target
284-
--timeout <TIMEOUT> Number of seconds to consider a hang when fuzzing or replaying
285-
(equivalent to -- -t <TIMEOUT * 1000> when fuzzing)
286-
--verbose Show build output when displaying/replaying
287-
-h, --help Print help
288-
-V, --version Print version
289-
290-
To fuzz at most <SECONDS> of time, use:
291-
292-
cargo test-fuzz ... -- -V <SECONDS>
293-
294-
Try `cargo afl fuzz --help` to see additional fuzzer options.
251+
--backtrace Display backtraces
252+
--consolidate Move one target's crashes, hangs, and work queue to its corpus; to
253+
consolidate all targets, use --consolidate-all
254+
--display <OBJECT> Display concretizations, corpus, crashes, `impl` concretizations,
255+
hangs, or work queue. By default, corpus uses an uninstrumented
256+
fuzz target; the others use an instrumented fuzz target. To
257+
display the corpus with instrumentation, use --display
258+
corpus-instrumented. [possible values: concretizations, corpus,
259+
corpus-instrumented, crashes, hangs, impl-concretizations, queue]
260+
--exact Target name is an exact name rather than a substring
261+
--exit-code Exit with 0 if the time limit was reached, 1 for other
262+
programmatic aborts, and 2 if an error occurred; implies --no-ui,
263+
does not imply --run-until-crash or --max-total-time <SECONDS>
264+
--features <FEATURES> Space or comma separated list of features to activate
265+
--fuzzer <FUZZER> Fuzz using <FUZZER> [possible values: aflplusplus,
266+
aflplusplus-persistent, libfuzzer]
267+
--list List fuzz targets
268+
--manifest-path <PATH> Path to Cargo.toml
269+
--max-total-time <SECONDS> Fuzz at most <SECONDS> of time (equivalent to -- -V <SECONDS> for
270+
aflplusplus, and -- --max_total_time <SECONDS> for libfuzzer)
271+
--no-default-features Do not activate the `default` feature
272+
--no-instrumentation Compile without instrumentation (for testing build process)
273+
--no-run Compile, but don't fuzz
274+
--no-ui Disable user interface
275+
-p, --package <PACKAGE> Package containing fuzz target
276+
--pretty-print Pretty-print debug output when displaying/replaying
277+
--replay <OBJECT> Replay corpus, crashes, hangs, or work queue. By default, corpus
278+
uses an uninstrumented fuzz target; the others use an instrumented
279+
fuzz target. To replay the corpus with instrumentation, use
280+
--replay corpus-instrumented. [possible values: concretizations,
281+
corpus, corpus-instrumented, crashes, hangs, impl-concretizations,
282+
queue]
283+
--reset Clear fuzzing data for one target, but leave corpus intact; to
284+
reset all targets, use --reset-all
285+
--resume Resume target's last fuzzing session
286+
--run-until-crash Stop fuzzing once a crash is found
287+
--test <NAME> Integration test containing fuzz target
288+
--timeout <TIMEOUT> Number of seconds to consider a hang when fuzzing or replaying
289+
(equivalent to -- -t <TIMEOUT * 1000> when fuzzing with
290+
aflplusplus, and -- -timeout <TIMEOUT> when fuzzing with
291+
libfuzzer)
292+
--verbose Show build output when displaying/replaying
293+
-h, --help Print help
294+
-V, --version Print version
295+
296+
Try `cargo afl fuzz --help` to see additional AFLplusplus options.
295297
```
296298

297299
### Convenience functions and macros

cargo-test-fuzz/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,20 @@ doctest = false
1919
[dependencies]
2020
anyhow = { version = "1.0", features = ["backtrace"] }
2121
bitflags = "2.3"
22+
cargo-fuzz = { git = "https://github.com/trail-of-forks/cargo-fuzz", features = ["no-manifest-check"] }
2223
cargo_metadata = "0.15"
2324
clap = { version = "4.3", features = ["cargo", "derive", "wrap_help"] }
2425
env_logger = "0.10"
26+
fs_extra = "1.3"
2527
heck = "0.4"
2628
lazy_static = "1.4"
2729
log = "0.4"
30+
once_cell = "1.16"
2831
paste = "1.0"
2932
remain = "0.2"
3033
semver = "1.0"
3134
serde = { version = "1.0", features = ["derive"] }
35+
serde_json = "1.0"
3236
strum_macros = "0.24"
3337
subprocess = "0.2"
3438

0 commit comments

Comments
 (0)