9 unstable releases (3 breaking)

0.4.0 Jul 17, 2023
0.3.0 Apr 7, 2023
0.2.3 Apr 1, 2023
0.2.0 Mar 22, 2023
0.1.2 Mar 21, 2023

#554 in Testing

Download history 149/week @ 2024-03-11 154/week @ 2024-03-18 101/week @ 2024-03-25 122/week @ 2024-04-01 96/week @ 2024-04-08 208/week @ 2024-04-15 142/week @ 2024-04-22 185/week @ 2024-04-29 105/week @ 2024-05-06 128/week @ 2024-05-13 211/week @ 2024-05-20 81/week @ 2024-05-27 129/week @ 2024-06-03 77/week @ 2024-06-10 51/week @ 2024-06-17 115/week @ 2024-06-24

374 downloads per month
Used in 7 crates

MIT license

18KB
312 lines

tree-crasher

tree-crasher is an easy-to-use grammar-based black-box fuzzer. It parses a number of input files using tree-sitter grammars, and produces new files formed by splicing together their ASTs.

tree-crasher aims to occupy a different niche from more advanced grammar-based fuzzers like Gramatron, Nautilus, and Grammarinator. Rather than achieve maximal coverage and bug-finding through complete, hand-written grammars and complex techniques like coverage-based feedback, tree-crasher aims to achieve maximal ease-of-use by using off-the-shelf tree-sitter grammars and not requiring any instrumentation (nor even source code) for the target. In short, tree-crasher wants to be the Radamsa of grammar-based fuzzing.

tree-crasher uses treereduce to automatically minimize generated test-cases.

For more information, see the documentation.

Examples

When reading these examples, keep in mind that fuzzing can cause unpredictable behaviors. Always fuzz in a VM or Docker container with a memory limit, no network access, and no important files.

JavaScript interpreters

Obtain a collection of JavaScript files and put them in corpus/ (for example, using this script). Then here's how to fuzz JerryScript and Boa:

tree-crasher-javascript corpus/ jerry
tree-crasher-javascript corpus/ boa

(By default, tree-crasher passes input to the target on stdin.)

Python's regex engine

Write rx.py like so:

import re
import sys
try:
    s = sys.stdin.read()
    r = re.compile(s)
    print(r.match(s))
except:
    pass

Put some sample regular expressions in corpus/. Then:

tree-crasher-regex corpus/ -- python3 $PWD/rx.py

rustc

tree-crasher has found many bugs in rustc. Here's how it was done! The special @@ symbol on the command line gets replaced by the file generated by tree-crasher.

tree-crasher-rust \
  --interesting-stderr "(?m)^error: internal compiler error:" \
  corpus \ 
  -- \
  rustc +nightly --crate-type=lib --emit=mir -Zmir-opt-level=4 @@.rs

(The regex syntax is that of the regex crate.)

More examples

See the documentation for more examples.

Bugs found

tree-crasher uses tree-splicer to generate test cases, see the list of bugs found in that project's README.

If you find a bug with tree-crasher, please let me know! One great way to do so would be to submit a PR to tree-splicer to add it to the README.

Supported languages

tree-crasher supports 9+ languages, see the documentation for details.

Documentation

Documentation is available online or in ./doc.

Dependencies

~7–18MB
~250K SLoC