Skip to content

Commit 6fea17f

Browse files
committed
fuzz: copy *.sh files from rust-bitcoin; tweak generate-files.sh
1 parent 7c28bd3 commit 6fea17f

File tree

4 files changed

+208
-0
lines changed

4 files changed

+208
-0
lines changed

fuzz/cycle.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env bash
2+
3+
# Continuosly cycle over fuzz targets running each for 1 hour.
4+
# It uses chrt SCHED_IDLE so that other process takes priority.
5+
#
6+
# For hfuzz options see https://github.com/google/honggfuzz/blob/master/docs/USAGE.md
7+
8+
set -e
9+
REPO_DIR=$(git rev-parse --show-toplevel)
10+
# shellcheck source=./fuzz-util.sh
11+
source "$REPO_DIR/fuzz/fuzz-util.sh"
12+
13+
while :
14+
do
15+
for targetFile in $(listTargetFiles); do
16+
targetName=$(targetFileToName "$targetFile")
17+
echo "Fuzzing target $targetName ($targetFile)"
18+
19+
# fuzz for one hour
20+
HFUZZ_RUN_ARGS='--run_time 3600' chrt -i 0 cargo hfuzz run "$targetName"
21+
# minimize the corpus
22+
HFUZZ_RUN_ARGS="-i hfuzz_workspace/$targetName/input/ -P -M" chrt -i 0 cargo hfuzz run "$targetName"
23+
done
24+
done
25+

fuzz/fuzz-util.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env bash
2+
3+
REPO_DIR=$(git rev-parse --show-toplevel)
4+
5+
listTargetFiles() {
6+
pushd "$REPO_DIR/fuzz" > /dev/null || exit 1
7+
find fuzz_targets/ -type f -name "*.rs"
8+
popd > /dev/null || exit 1
9+
}
10+
11+
targetFileToName() {
12+
echo "$1" \
13+
| sed 's/^fuzz_targets\///' \
14+
| sed 's/\.rs$//' \
15+
| sed 's/\//_/g'
16+
}
17+
18+
targetFileToHFuzzInputArg() {
19+
baseName=$(basename "$1")
20+
dirName="${baseName%.*}"
21+
if [ -d "hfuzz_input/$dirName" ]; then
22+
echo "HFUZZ_INPUT_ARGS=\"-f hfuzz_input/$FILE/input\""
23+
fi
24+
}
25+
26+
listTargetNames() {
27+
for target in $(listTargetFiles); do
28+
targetFileToName "$target"
29+
done
30+
}
31+
32+
# Utility function to avoid CI failures on Windows
33+
checkWindowsFiles() {
34+
incorrectFilenames=$(find . -type f -name "*,*" -o -name "*:*" -o -name "*<*" -o -name "*>*" -o -name "*|*" -o -name "*\?*" -o -name "*\**" -o -name "*\"*" | wc -l)
35+
if [ "$incorrectFilenames" -gt 0 ]; then
36+
echo "Bailing early because there is a Windows-incompatible filename in the tree."
37+
exit 2
38+
fi
39+
}
40+
41+
# Checks whether a fuzz case output some report, and dumps it in hex
42+
checkReport() {
43+
reportFile="hfuzz_workspace/$1/HONGGFUZZ.REPORT.TXT"
44+
if [ -f "$reportFile" ]; then
45+
cat "$reportFile"
46+
for CASE in "hfuzz_workspace/$1/SIG"*; do
47+
xxd -p -c10000 < "$CASE"
48+
done
49+
exit 1
50+
fi
51+
}

fuzz/fuzz.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env bash
2+
set -ex
3+
4+
REPO_DIR=$(git rev-parse --show-toplevel)
5+
6+
# shellcheck source=./fuzz-util.sh
7+
source "$REPO_DIR/fuzz/fuzz-util.sh"
8+
9+
# Check that input files are correct Windows file names
10+
checkWindowsFiles
11+
12+
if [ "$1" == "" ]; then
13+
targetFiles="$(listTargetFiles)"
14+
else
15+
targetFiles=fuzz_targets/"$1".rs
16+
fi
17+
18+
cargo --version
19+
rustc --version
20+
21+
# Testing
22+
cargo install --force honggfuzz --no-default-features
23+
for targetFile in $targetFiles; do
24+
targetName=$(targetFileToName "$targetFile")
25+
echo "Fuzzing target $targetName ($targetFile)"
26+
if [ -d "hfuzz_input/$targetName" ]; then
27+
HFUZZ_INPUT_ARGS="-f hfuzz_input/$targetName/input\""
28+
else
29+
HFUZZ_INPUT_ARGS=""
30+
fi
31+
HFUZZ_RUN_ARGS="--run_time 30 --exit_upon_crash -v $HFUZZ_INPUT_ARGS" cargo hfuzz run "$targetName"
32+
33+
checkReport "$targetName"
34+
done

fuzz/generate-files.sh

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
REPO_DIR=$(git rev-parse --show-toplevel)
6+
7+
# shellcheck source=./fuzz-util.sh
8+
source "$REPO_DIR/fuzz/fuzz-util.sh"
9+
10+
# 1. Generate fuzz/Cargo.toml
11+
cat > "$REPO_DIR/fuzz/Cargo.toml" <<EOF
12+
[package]
13+
name = "descriptor-fuzz"
14+
edition = "2018"
15+
version = "0.0.1"
16+
authors = ["Generated by fuzz/generate-files.sh"]
17+
publish = false
18+
19+
[package.metadata]
20+
cargo-fuzz = true
21+
22+
[dependencies]
23+
honggfuzz = { version = "0.5.55", default-features = false }
24+
miniscript = { path = "..", features = [ "compiler" ] }
25+
26+
regex = "1.4"
27+
EOF
28+
29+
for targetFile in $(listTargetFiles); do
30+
targetName=$(targetFileToName "$targetFile")
31+
cat >> "$REPO_DIR/fuzz/Cargo.toml" <<EOF
32+
33+
[[bin]]
34+
name = "$targetName"
35+
path = "$targetFile"
36+
EOF
37+
done
38+
39+
# 2. Generate .github/workflows/fuzz.yml
40+
cat > "$REPO_DIR/.github/workflows/fuzz.yml" <<EOF
41+
# Automatically generated by fuzz/generate-files.sh
42+
name: Fuzz
43+
44+
on:
45+
push:
46+
branches:
47+
- master
48+
- 'test-ci/**'
49+
pull_request:
50+
51+
jobs:
52+
fuzz:
53+
if: \${{ !github.event.act }}
54+
runs-on: ubuntu-20.04
55+
strategy:
56+
fail-fast: false
57+
matrix:
58+
fuzz_target: [
59+
$(for name in $(listTargetNames); do echo "$name,"; done)
60+
]
61+
steps:
62+
- name: Install test dependencies
63+
run: sudo apt-get update -y && sudo apt-get install -y binutils-dev libunwind8-dev libcurl4-openssl-dev libelf-dev libdw-dev cmake gcc libiberty-dev
64+
- uses: actions/checkout@v2
65+
- uses: actions/cache@v2
66+
id: cache-fuzz
67+
with:
68+
path: |
69+
~/.cargo/bin
70+
fuzz/target
71+
target
72+
key: cache-\${{ matrix.target }}-\${{ hashFiles('**/Cargo.toml','**/Cargo.lock') }}
73+
- uses: actions-rs/toolchain@v1
74+
with:
75+
toolchain: 1.58
76+
override: true
77+
profile: minimal
78+
- name: fuzz
79+
run: cd fuzz && ./fuzz.sh "\${{ matrix.fuzz_target }}"
80+
- run: echo "\${{ matrix.fuzz_target }}" >executed_\${{ matrix.fuzz_target }}
81+
- uses: actions/upload-artifact@v2
82+
with:
83+
name: executed_\${{ matrix.fuzz_target }}
84+
path: executed_\${{ matrix.fuzz_target }}
85+
86+
verify-execution:
87+
if: \${{ !github.event.act }}
88+
needs: fuzz
89+
runs-on: ubuntu-latest
90+
steps:
91+
- uses: actions/checkout@v2
92+
- uses: actions/download-artifact@v2
93+
- name: Display structure of downloaded files
94+
run: ls -R
95+
- run: find executed_* -type f -exec cat {} + | sort > executed
96+
- run: source ./fuzz/fuzz-util.sh && listTargetNames | sort | diff - executed
97+
EOF
98+

0 commit comments

Comments
 (0)