Skip to content

Commit 524c395

Browse files
committed
fuzz: switch from honggfuzz to cargo-fuzz
honggfuzz is increasingly hard for me to maintain in my local CI. It requires an exact match between the version of honggfuzz in the lockfile and the binary installed in the nix derivation, and these exact versions come with specific requirements about which rustc versions are allowable (and in particular, honggfuzz 0.5.56 does not work with rustc 1.74.0, which is the MSRV for rust-bitcoin). I also have to bend over backward to set compiler flags and make source directories writable. cargo-fuzz, meanwhile, requires nightly to *run* the fuzz tests, but does not require it for just running unit tests or building. (The latest version of libfuzzer-sys uses once_cell and requires a higher MSRV than we have, but we don't need to use the very latest version.)
1 parent 4ea7fcf commit 524c395

22 files changed

+302
-236
lines changed

.github/workflows/cron-daily-fuzz.yml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,21 @@ on:
99
- cron: '00 06 * * *'
1010

1111
jobs:
12+
Prepare:
13+
runs-on: ubuntu-24.04
14+
outputs:
15+
nightly_version: ${{ steps.read_toolchain.outputs.nightly_version }}
16+
steps:
17+
- name: "Checkout repo"
18+
uses: actions/checkout@v4
19+
- name: "Read nightly version"
20+
id: read_toolchain
21+
run: echo "nightly_version=$(cat nightly-version)" >> $GITHUB_OUTPUT
22+
1223
fuzz:
1324
if: ${{ !github.event.act }}
14-
runs-on: ubuntu-20.04
25+
needs: Prepare
26+
runs-on: ubuntu-25.04
1527
strategy:
1628
fail-fast: false
1729
matrix:
@@ -47,9 +59,15 @@ roundtrip_semantic,
4759
fuzz/target
4860
target
4961
key: cache-${{ matrix.target }}-${{ hashFiles('**/Cargo.toml','**/Cargo.lock') }}
62+
63+
- name: Install toolchain
5064
- uses: dtolnay/rust-toolchain@stable
5165
with:
52-
toolchain: '1.65.0'
66+
toolchain: ${{ needs.Prepare.outputs.nightly_version }}
67+
68+
- name: Install Dependencies
69+
run: cargo update && cargo update -p cc --precise 1.0.83 && cargo install --force cargo-fuzz
70+
5371
- name: fuzz
5472
run: cd fuzz && ./fuzz.sh "${{ matrix.fuzz_target }}"
5573
- run: echo "${{ matrix.fuzz_target }}" >executed_${{ matrix.fuzz_target }}
@@ -63,7 +81,7 @@ roundtrip_semantic,
6381
needs: fuzz
6482
runs-on: ubuntu-latest
6583
steps:
66-
- uses: actions/checkout@v2
84+
- uses: actions/checkout@v4
6785
- uses: actions/download-artifact@v4
6886
- name: Display structure of downloaded files
6987
run: ls -R

Cargo-minimal.lock

Lines changed: 17 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ dependencies = [
1111
"memchr",
1212
]
1313

14+
[[package]]
15+
name = "arbitrary"
16+
version = "1.4.2"
17+
source = "registry+https://github.com/rust-lang/crates.io-index"
18+
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
19+
1420
[[package]]
1521
name = "arrayvec"
1622
version = "0.7.4"
@@ -110,7 +116,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
110116
name = "descriptor-fuzz"
111117
version = "0.0.1"
112118
dependencies = [
113-
"honggfuzz",
119+
"libfuzzer-sys",
114120
"miniscript 12.3.0",
115121
"miniscript 13.0.0",
116122
"regex",
@@ -148,43 +154,27 @@ version = "0.1.1"
148154
source = "registry+https://github.com/rust-lang/crates.io-index"
149155
checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd"
150156

151-
[[package]]
152-
name = "honggfuzz"
153-
version = "0.5.56"
154-
source = "registry+https://github.com/rust-lang/crates.io-index"
155-
checksum = "7c76b6234c13c9ea73946d1379d33186151148e0da231506b964b44f3d023505"
156-
dependencies = [
157-
"lazy_static",
158-
"memmap2",
159-
"rustc_version",
160-
]
161-
162-
[[package]]
163-
name = "lazy_static"
164-
version = "1.4.0"
165-
source = "registry+https://github.com/rust-lang/crates.io-index"
166-
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
167-
168157
[[package]]
169158
name = "libc"
170159
version = "0.2.154"
171160
source = "registry+https://github.com/rust-lang/crates.io-index"
172161
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
173162

174163
[[package]]
175-
name = "memchr"
176-
version = "2.5.0"
164+
name = "libfuzzer-sys"
165+
version = "0.4.0"
177166
source = "registry+https://github.com/rust-lang/crates.io-index"
178-
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
167+
checksum = "86c975d637bc2a2f99440932b731491fc34c7f785d239e38af3addd3c2fd0e46"
168+
dependencies = [
169+
"arbitrary",
170+
"cc",
171+
]
179172

180173
[[package]]
181-
name = "memmap2"
182-
version = "0.9.4"
174+
name = "memchr"
175+
version = "2.5.0"
183176
source = "registry+https://github.com/rust-lang/crates.io-index"
184-
checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322"
185-
dependencies = [
186-
"libc",
187-
]
177+
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
188178

189179
[[package]]
190180
name = "miniscript"
@@ -279,15 +269,6 @@ version = "0.6.29"
279269
source = "registry+https://github.com/rust-lang/crates.io-index"
280270
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
281271

282-
[[package]]
283-
name = "rustc_version"
284-
version = "0.4.0"
285-
source = "registry+https://github.com/rust-lang/crates.io-index"
286-
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
287-
dependencies = [
288-
"semver",
289-
]
290-
291272
[[package]]
292273
name = "secp256k1"
293274
version = "0.29.0"
@@ -309,12 +290,6 @@ dependencies = [
309290
"cc",
310291
]
311292

312-
[[package]]
313-
name = "semver"
314-
version = "1.0.22"
315-
source = "registry+https://github.com/rust-lang/crates.io-index"
316-
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
317-
318293
[[package]]
319294
name = "serde"
320295
version = "1.0.199"

Cargo-recent.lock

Lines changed: 35 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ dependencies = [
1111
"memchr",
1212
]
1313

14+
[[package]]
15+
name = "arbitrary"
16+
version = "1.4.2"
17+
source = "registry+https://github.com/rust-lang/crates.io-index"
18+
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
19+
1420
[[package]]
1521
name = "arrayvec"
1622
version = "0.7.4"
@@ -96,9 +102,13 @@ dependencies = [
96102

97103
[[package]]
98104
name = "cc"
99-
version = "1.0.28"
105+
version = "1.2.36"
100106
source = "registry+https://github.com/rust-lang/crates.io-index"
101-
checksum = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749"
107+
checksum = "5252b3d2648e5eedbc1a6f501e3c795e07025c1e93bbf8bbdd6eef7f447a6d54"
108+
dependencies = [
109+
"find-msvc-tools",
110+
"shlex",
111+
]
102112

103113
[[package]]
104114
name = "cfg-if"
@@ -110,12 +120,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
110120
name = "descriptor-fuzz"
111121
version = "0.0.1"
112122
dependencies = [
113-
"honggfuzz",
123+
"libfuzzer-sys",
114124
"miniscript 12.3.0",
115125
"miniscript 13.0.0",
116126
"regex",
117127
]
118128

129+
[[package]]
130+
name = "find-msvc-tools"
131+
version = "0.1.1"
132+
source = "registry+https://github.com/rust-lang/crates.io-index"
133+
checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d"
134+
119135
[[package]]
120136
name = "getrandom"
121137
version = "0.2.14"
@@ -148,43 +164,27 @@ version = "0.1.1"
148164
source = "registry+https://github.com/rust-lang/crates.io-index"
149165
checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd"
150166

151-
[[package]]
152-
name = "honggfuzz"
153-
version = "0.5.56"
154-
source = "registry+https://github.com/rust-lang/crates.io-index"
155-
checksum = "7c76b6234c13c9ea73946d1379d33186151148e0da231506b964b44f3d023505"
156-
dependencies = [
157-
"lazy_static",
158-
"memmap2",
159-
"rustc_version",
160-
]
161-
162-
[[package]]
163-
name = "lazy_static"
164-
version = "1.4.0"
165-
source = "registry+https://github.com/rust-lang/crates.io-index"
166-
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
167-
168167
[[package]]
169168
name = "libc"
170169
version = "0.2.154"
171170
source = "registry+https://github.com/rust-lang/crates.io-index"
172171
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
173172

174173
[[package]]
175-
name = "memchr"
176-
version = "2.5.0"
174+
name = "libfuzzer-sys"
175+
version = "0.4.1"
177176
source = "registry+https://github.com/rust-lang/crates.io-index"
178-
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
177+
checksum = "8a9dc6556604b8ad76486563d5a47fad989b643932fa006e76e23d948bef0f5b"
178+
dependencies = [
179+
"arbitrary",
180+
"cc",
181+
]
179182

180183
[[package]]
181-
name = "memmap2"
182-
version = "0.9.4"
184+
name = "memchr"
185+
version = "2.5.0"
183186
source = "registry+https://github.com/rust-lang/crates.io-index"
184-
checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322"
185-
dependencies = [
186-
"libc",
187-
]
187+
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
188188

189189
[[package]]
190190
name = "miniscript"
@@ -279,15 +279,6 @@ version = "0.6.29"
279279
source = "registry+https://github.com/rust-lang/crates.io-index"
280280
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
281281

282-
[[package]]
283-
name = "rustc_version"
284-
version = "0.4.0"
285-
source = "registry+https://github.com/rust-lang/crates.io-index"
286-
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
287-
dependencies = [
288-
"semver",
289-
]
290-
291282
[[package]]
292283
name = "secp256k1"
293284
version = "0.29.0"
@@ -309,12 +300,6 @@ dependencies = [
309300
"cc",
310301
]
311302

312-
[[package]]
313-
name = "semver"
314-
version = "1.0.22"
315-
source = "registry+https://github.com/rust-lang/crates.io-index"
316-
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
317-
318303
[[package]]
319304
name = "serde"
320305
version = "1.0.199"
@@ -344,6 +329,12 @@ dependencies = [
344329
"serde",
345330
]
346331

332+
[[package]]
333+
name = "shlex"
334+
version = "1.3.0"
335+
source = "registry+https://github.com/rust-lang/crates.io-index"
336+
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
337+
347338
[[package]]
348339
name = "syn"
349340
version = "2.0.56"

fuzz/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@ publish = false
1010
cargo-fuzz = true
1111

1212
[dependencies]
13-
honggfuzz = { version = "0.5.56", default-features = false }
13+
libfuzzer-sys = "0.4"
1414
# We shouldn't need an explicit version on the next line, but Andrew's tools
1515
# choke on it otherwise. See https://github.com/nix-community/crate2nix/issues/373
1616
miniscript = { path = "..", features = [ "compiler" ], version = "13.0" }
1717
old_miniscript = { package = "miniscript", features = [ "compiler" ], version = "12.3" }
1818

1919
regex = "1.0"
2020

21+
[lints.rust]
22+
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }
23+
2124
[[bin]]
2225
name = "compile_descriptor"
2326
path = "fuzz_targets/compile_descriptor.rs"

fuzz/fuzz.sh

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#!/usr/bin/env bash
2-
set -ex
2+
set -o errexit # exit immediately if any command fails
3+
set -o xtrace # print trace of executed commands
34

4-
REPO_DIR=$(git rev-parse --show-toplevel || jj workspace show)
5+
REPO_DIR=$(git rev-parse --show-toplevel)
56

6-
# can't find the file because of the ENV var
7-
# shellcheck source=/dev/null
7+
# shellcheck source=./fuzz/fuzz-util.sh
88
source "$REPO_DIR/fuzz/fuzz-util.sh"
99

1010
# Check that input files are correct Windows file names
@@ -19,17 +19,8 @@ fi
1919
cargo --version
2020
rustc --version
2121

22-
# Testing
23-
cargo install --force honggfuzz --no-default-features
22+
# Run fuzz target
2423
for targetFile in $targetFiles; do
2524
targetName=$(targetFileToName "$targetFile")
26-
echo "Fuzzing target $targetName ($targetFile)"
27-
if [ -d "hfuzz_input/$targetName" ]; then
28-
HFUZZ_INPUT_ARGS="-f hfuzz_input/$targetName/input\""
29-
else
30-
HFUZZ_INPUT_ARGS=""
31-
fi
32-
HFUZZ_RUN_ARGS="--run_time 30 --exit_upon_crash -v $HFUZZ_INPUT_ARGS" cargo hfuzz run "$targetName"
33-
34-
checkReport "$targetName"
25+
cargo-fuzz run "$targetName" -- -max_total_time=30
3526
done

fuzz/fuzz_targets/compile_descriptor.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
#![allow(unexpected_cfgs)]
1+
// SPDX-License-Identifier: CC0-1.0
2+
3+
#![cfg_attr(fuzzing, no_main)]
24

35
use std::str::FromStr;
46

5-
use honggfuzz::fuzz;
67
use miniscript::{policy, Miniscript, Segwitv0};
78
use policy::Liftable;
89

@@ -28,10 +29,19 @@ fn do_test(data: &[u8]) {
2829
}
2930
}
3031

31-
fn main() {
32-
loop {
33-
fuzz!(|data| {
34-
do_test(data);
35-
});
32+
#[cfg(fuzzing)]
33+
libfuzzer_sys::fuzz_target!(|data| do_test(data));
34+
35+
#[cfg(not(fuzzing))]
36+
fn main() { do_test(&[]); }
37+
38+
#[cfg(test)]
39+
mod tests {
40+
use miniscript::hex;
41+
42+
#[test]
43+
fn duplicate_crash() {
44+
let v = hex::decode_to_vec("abcd").unwrap();
45+
super::do_test(&v);
3646
}
3747
}

0 commit comments

Comments
 (0)