Skip to content

Commit 31a0e85

Browse files
committed
Updating utils scripts
1 parent 199bbcd commit 31a0e85

File tree

5 files changed

+82
-219
lines changed

5 files changed

+82
-219
lines changed

fuzz_to_test_cases.py

Lines changed: 0 additions & 206 deletions
This file was deleted.

queue_to_new_inputs.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import hashlib
2+
import multiprocessing
3+
import os
4+
import pathlib
5+
import subprocess
6+
import sys
7+
import functools
8+
import tempfile
9+
10+
# Workflow taken from this blog post on how to fuzz effectively
11+
# https://foxglovesecurity.com/2016/03/15/fuzzing-workflows-a-fuzz-job-from-start-to-finish/
12+
13+
14+
ROOT = pathlib.Path(__file__).parent
15+
16+
17+
def list_files_in_folder(*folders):
18+
folders = [folder for folder in folders if folder.is_dir()]
19+
return {f for folder in folders for f in folder.iterdir() if f.is_file()}
20+
21+
22+
def load_files_in_folder(*folders):
23+
return {f.read_bytes() for f in list_files_in_folder(*folders)}
24+
25+
26+
def minimise_inputs(executable, out_folder, items):
27+
with tempfile.TemporaryDirectory(dir=ROOT) as _td:
28+
td = pathlib.Path(_td)
29+
assert td.is_dir()
30+
for i, item in enumerate(sorted(items, key=lambda d: (len(d), d))):
31+
if 0 < len(item) <= 4096:
32+
(td / f"input_{i}").write_bytes(item)
33+
subprocess.run(
34+
["afl-cmin", "-i", td, "-o", out_folder, "--", executable], check=True
35+
)
36+
37+
38+
def minimise_input(executable, out_folder, file):
39+
out = out_folder / file.name
40+
subprocess.run(["afl-tmin", "-i", file, "-o", out, "--", executable], check=True)
41+
42+
43+
def main():
44+
executable = pathlib.Path(sys.argv[1])
45+
assert executable.is_file()
46+
folders = [f for f in map(pathlib.Path, sys.argv[2:]) if f.is_dir()]
47+
new_corpus = load_files_in_folder(*folders)
48+
count = 0
49+
cmin_out = ROOT / f"_cmin_{count}_corpus"
50+
tmin_out = ROOT / f"_tmin_{count}_corpus"
51+
subprocess.run(["rm", "-rf", cmin_out, tmin_out], check=True)
52+
tmin_out.mkdir(exist_ok=True)
53+
minimise_inputs(executable, cmin_out, new_corpus)
54+
with multiprocessing.Pool(32) as p:
55+
p.map(
56+
functools.partial(minimise_input, executable, tmin_out),
57+
list_files_in_folder(cmin_out),
58+
)
59+
60+
61+
if __name__ == "__main__":
62+
main()

test_case_gen.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
101: "Rust Panic",
2828
134: "C Abort",
2929
-6: "C Abort",
30-
999: "Python Timeout",
30+
# 999: "Python Timeout",
3131
}
3232

3333
KCOV_COMMON_OPTS = []
@@ -53,12 +53,13 @@ def kcov_collect(dir):
5353
TEST_OUTPUT_DIRS = {
5454
name: TEST_OUTPUT_ROOT_DIR / name
5555
for name in [
56-
"match",
57-
"match_err",
58-
"match_crash",
56+
'timeout',
5957
"crash",
60-
"difference_out",
6158
"difference_err",
59+
"difference_out",
60+
"match_crash",
61+
"match_err",
62+
"match",
6263
"unknown",
6364
"wip",
6465
]
@@ -201,10 +202,10 @@ def bytes_to_rust_array(data):
201202
for b in data:
202203
aparts.append(f"0x{b:02X},")
203204
if len(aparts) >= 16:
204-
out += f'{" ".join(aparts)}\n'
205+
out += f'{" ".join(aparts)}\n'
205206
aparts = []
206207
if aparts:
207-
out += f'{" ".join(aparts)}\n'
208+
out += f'{" ".join(aparts)}\n'
208209
return f"[\n{out}]\n"
209210
def output_test_case(
210211
input,
@@ -218,17 +219,20 @@ def output_test_case(
218219
fail_type,
219220
):
220221
name = test_case_name(input)
222+
if fail_type not in TEST_OUTPUT_DIRS:
223+
print(f"You forgot a fail_type({fail_type!r}). I got you fam")
224+
TEST_OUTPUT_DIRS[fail_type] = TEST_OUTPUT_ROOT_DIR / fail_type
221225
out = TEST_OUTPUT_DIRS[fail_type] / name
222226
sp_run(["rm", "-rf", out], check=True)
223227
out.mkdir(parents=True)
224228
(out / "input.dat").write_bytes(input)
225229
(out / "input.txt").write_text(bytes_to_test_hex(input))
226-
(out / "input.txt").write_text(bytes_to_rust_array(input))
230+
(out / "input.rs").write_text(bytes_to_rust_array(input))
227231
for (o, name) in [(sys_out, "sys_"), (new_out, "new_")]:
228232
if o is not None:
229233
(out / f"{name}output.dat").write_bytes(o)
230234
(out / f"{name}output.txt").write_text(bytes_to_test_hex(o))
231-
(out / f"{name}output.txt").write_text(bytes_to_rust_array(o))
235+
(out / f"{name}output.rs").write_text(bytes_to_rust_array(o))
232236
for (o, name) in [(sys_err, "sys_"), (new_err, "new_")]:
233237
if o is not None:
234238
(out / f"{name}err.txt").write_bytes(o)
@@ -281,7 +285,9 @@ def run(input: bytes):
281285
if not new_known_err:
282286
print("Unknown error: ", new_err)
283287

284-
if sys_rc == 0:
288+
if new_rc == 999:
289+
fail_type = 'timeout'
290+
elif sys_rc == 0:
285291
if new_rc != 0:
286292
fail_type = "difference_err"
287293
elif sys_out != new_out:

file_to_test_case.py renamed to utils/file_to_test_case.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import sys
66
import tempfile
77

8-
ROOT = pathlib.Path(__file__).parent
8+
ROOT = pathlib.Path(__file__).parent.parent
99
FUZZ_DIR = ROOT / "fuzz"
1010
FUZZ_CRASHES_DIR = FUZZ_DIR / "artifacts"
1111
AFL_OUTPUT_DIR = FUZZ_DIR / "afl_out"

hus_vip_to_test_case.py renamed to utils/hus_vip_to_test_case.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
offset = [20, 24, 28]
77

8-
ROOT = pathlib.Path(__file__).parent
8+
ROOT = pathlib.Path(__file__).parent.parent
99
NON_ALPHA = re.compile("(^[0-9]|[^a-zA-Z0-9_])")
1010

1111

@@ -47,7 +47,7 @@ def get_hus_vip_parts(data):
4747

4848

4949
def main():
50-
out_folder = ROOT / "old_tests/"
50+
out_folder = ROOT / "tests/"
5151
out_folder.mkdir(exist_ok=True)
5252
fuzz_inputs = ROOT / "_known_inputs"
5353
fuzz_inputs.mkdir(exist_ok=True)
@@ -57,6 +57,7 @@ def main():
5757
data = get_hus_vip_parts(p.read_bytes())
5858

5959
with (out_folder / f"{name}.rs").open("w") as f:
60+
f.write("#[macro_use]\nmod macros;\n\n")
6061
f.write("test_match_sys_decompress! {\n")
6162
for (name, compressed_data) in sorted(data.items()):
6263
f.write(

0 commit comments

Comments
 (0)