update the README to reflect recent decisions
parent
168332e84a
commit
6549bb51ca
137
README.md
137
README.md
|
@ -1,7 +1,7 @@
|
||||||
Fuzz Targets
|
Fuzz Targets
|
||||||
============
|
============
|
||||||
|
|
||||||
The files in this directory are fuzzing targets for wolfSSL. They follow the
|
The files in this repository are fuzzing targets for wolfSSL. They follow the
|
||||||
LLVM libFuzzer API and have a very specific naming scheme for integration with
|
LLVM libFuzzer API and have a very specific naming scheme for integration with
|
||||||
[Google's OSS-Fuzz service][oss-fuzz]. For more information about these
|
[Google's OSS-Fuzz service][oss-fuzz]. For more information about these
|
||||||
qualities, see [the section on making new targets](#new_target) below. To be
|
qualities, see [the section on making new targets](#new_target) below. To be
|
||||||
|
@ -9,7 +9,7 @@ run, they must be linked against `libFuzzer.a`. For more information about
|
||||||
compilation, see [the section on compiling](#compiling_target) below.
|
compilation, see [the section on compiling](#compiling_target) below.
|
||||||
|
|
||||||
[The very last section of this README](#future) is meant to document the
|
[The very last section of this README](#future) is meant to document the
|
||||||
foreseeable future of this directory, including suggestions on what fuzz
|
foreseeable future of this repository, including suggestions on what fuzz
|
||||||
targets should be written next. It is requested that future editors of this
|
targets should be written next. It is requested that future editors of this
|
||||||
directory update that section to reflect their work and thoughts.
|
directory update that section to reflect their work and thoughts.
|
||||||
|
|
||||||
|
@ -25,20 +25,21 @@ For information on how to get a target running inside of OSS-Fuzz, see [the
|
||||||
section on OSS-Fuzz](#with_oss-fuzz) below.
|
section on OSS-Fuzz](#with_oss-fuzz) below.
|
||||||
|
|
||||||
For the entirety of this section, let "`fuzz_target`" be a stand-in for the
|
For the entirety of this section, let "`fuzz_target`" be a stand-in for the
|
||||||
name of your target. It will be identical to the file name of the source code,
|
name of your target. It will be identical to the directory name containing the
|
||||||
but with out the ".c" extension.
|
source code.
|
||||||
|
|
||||||
If you have access to the make utility, everything will be simple: simply
|
If you have access to the make utility, everything will be simple. Before
|
||||||
execute `make fuzz_target` to compile it. If necessary, make will automatically
|
compiling any individual target, run `make deps`. If necessary, make will
|
||||||
retrieve the libFuzzer library and the most recent version of clang, both of
|
automatically retrieve the libFuzzer library and the most recent version of
|
||||||
which are required for compilation. Neither are installed, but kept locally
|
clang, both of which are required for compilation. Neither are installed, but
|
||||||
instead. If you wish to get these dependencies explicitly, call `make deps` or
|
kept locally instead. `make dependencies` is synonymous.
|
||||||
`make dependencies`. They are synonymous
|
|
||||||
|
|
||||||
Furthermore, running `make` or `make all` will compile all files ending in ".c"
|
From there, simply execute `make fuzz_target` to compile a fuzz target.
|
||||||
as fuzz targets, running `make clean` will delete the compiled fuzz targets but
|
|
||||||
leave the source files intact, and running `make spotless` will act like `make
|
Furthermore, running `make` or `make all` will compile all fuzz targets,
|
||||||
clean` but also delete libFuzzer and clang.
|
running `make clean` will delete the compiled fuzz targets but leave the source
|
||||||
|
files intact, and running `make spotless` will act like `make clean` but also
|
||||||
|
delete the dependencies build by `make deps`.
|
||||||
|
|
||||||
If you don't have access to make, you're going to have to do it all by hand.
|
If you don't have access to make, you're going to have to do it all by hand.
|
||||||
What follows for the rest of this section are the instructions for doing what
|
What follows for the rest of this section are the instructions for doing what
|
||||||
|
@ -57,8 +58,10 @@ The first thing to do is to get libFuzzer. To do this, run these commands from
|
||||||
the shell:
|
the shell:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git clone https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer Fuzzer
|
$ url=https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer
|
||||||
|
$ git clone $url Fuzzer
|
||||||
$ ./Fuzzer/build.sh
|
$ ./Fuzzer/build.sh
|
||||||
|
$ rm -rf Fuzzer
|
||||||
```
|
```
|
||||||
|
|
||||||
The above clones in the libFuzzer git repository then builds it. There should
|
The above clones in the libFuzzer git repository then builds it. There should
|
||||||
|
@ -71,48 +74,44 @@ use those tools to pull down the most up-to-date version of clang then make a
|
||||||
link for our convenience. In all, that looks like this:
|
link for our convenience. In all, that looks like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ export CLANG_TOOLS=https://chromium.googlesource.com/chromium/src/tools/clang
|
$ url=https://chromium.googlesource.com/chromium/src/tools/clang
|
||||||
$ git clone $CLANG_TOOLS new_clang/clang/clang
|
$ git clone $url new_clang/clang/clang
|
||||||
$ python new_clang/clang/clang/scripts/update.py
|
$ python new_clang/clang/clang/scripts/update.py
|
||||||
$ cp -s -t . new_clang/third_party/llvm-build/Release+Asserts/bin/clang{,++}
|
$ ln -s -t . new_clang/third_party/llvm-build/Release+Asserts/bin/clang{,++}
|
||||||
```
|
```
|
||||||
|
|
||||||
And with that, you now have a recent version of clang. It has not been
|
And with that, you now have a recent version of clang. It has not been
|
||||||
installed, so to use it you'll have to call clang like
|
installed, so to use it you'll have to call clang like `./clang` from this
|
||||||
```
|
directory.
|
||||||
$ ./clang
|
|
||||||
```
|
|
||||||
from this directory. Alternatively, you could call it like
|
|
||||||
```
|
|
||||||
$ ./new_clang/third_party/llvm-build/Release+Asserts/bin/clang
|
|
||||||
```
|
|
||||||
but that's a huge command. That's why we make links.
|
|
||||||
|
|
||||||
To compile, run these commands from the shell:
|
To compile, run these commands from the shell:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./clang -fsanitize=address -fsanitize-coverage=trace-pc-guard -c fuzz_target.c -o fuzz_target.o
|
$ CFLAGS="-fsanitize=address -fsanitize-coverage=trace-pc-guard"
|
||||||
$ ./clang++ -fsanitize=address -fsanitize-coverage=trace-pc-guard fuzz_target.o -L. -lwolfssl -lFuzzer -o fuzz_target
|
$ LDFLAGS="-L. -lwolfssl -lFuzzer"
|
||||||
|
$ ./clang $CFLAGS -c fuzz_target/target.c -o fuzz_target/target.o
|
||||||
|
$ ./clang++ $CFLAGS fuzz_target/target.o -o fuzz_target/target $LDFLAGS
|
||||||
$ rm fuzz_target.o
|
$ rm fuzz_target.o
|
||||||
```
|
```
|
||||||
|
|
||||||
And with that, `fuzz_target` has been compiled. This compile step is the only
|
And with that, `fuzz_target` has been compiled. This compile step is the only
|
||||||
|
|
||||||
<a name="run_target">Running Targets</a>
|
<a name="run_target">Running Targets</a>
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
For the entirety of this section, let "`fuzz_target`" be a stand-in for the
|
For the entirety of this section, let "`fuzz_target`" be a stand-in for the
|
||||||
name of your target. It will be identical to the file name of the source code,
|
name of your target. It will be identical to the directory name containing
|
||||||
but with out the ".c" extention.
|
the source code.
|
||||||
|
|
||||||
After compiling, `fuzz_target` is an executable that can be called like this:
|
After compiling, `cd` into `fuzz_target/`, and `target` is an executable that
|
||||||
|
can be called like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./fuzz_target [OPTION ...] [CORPUS ...]
|
$ ./target [OPTION ...] [CORPUS ...]
|
||||||
```
|
```
|
||||||
or
|
or
|
||||||
```
|
```
|
||||||
$ ./fuzz_target [OPTION ...] [FILE ...]
|
$ ./target [OPTION ...] [FILE ...]
|
||||||
```
|
```
|
||||||
|
|
||||||
A corpus is a directory with files containing example input data, good or bad,
|
A corpus is a directory with files containing example input data, good or bad,
|
||||||
|
@ -137,34 +136,33 @@ fuzz target: [source code](#target_src), [options](#target_opt), and
|
||||||
[corpus](#target_corp). See their respective subsections below for more
|
[corpus](#target_corp). See their respective subsections below for more
|
||||||
information on each.
|
information on each.
|
||||||
|
|
||||||
All three parts must be placed in the same directory with all the other fuzz
|
All three parts must be placed in the same directory, but separate from any
|
||||||
targets. There are no exceptions; failure to comply with this will prevent your
|
other fuzz target. The name of this directory will be the name of the fuzz
|
||||||
|
target. There are no exceptions; failure to comply with this will prevent your
|
||||||
fuzz target from being found by OSS-Fuzz.
|
fuzz target from being found by OSS-Fuzz.
|
||||||
|
|
||||||
The only required part is the source code; options files and corpuses (corpi?)
|
The only required part is the source code; options files and corpora may be
|
||||||
may be omitted, though it is recommended that you include all three components.
|
omitted, though it is recommended that you at least also include a corpus.
|
||||||
|
|
||||||
The fourth, extra optional part is the dictionary. You can read more about how
|
The fourth, extra optional part is the dictionary. You can read more about how
|
||||||
to use or include them in [the OSS-Fuzz documentation][dict]. If you wish to
|
to use or include them in [the OSS-Fuzz documentation][dict]. If you wish to
|
||||||
include one, create a file ending in ".dict" in this directory, then add a line
|
include one, create a file ending in ".dict" in the root directory of this
|
||||||
like this to the options file for the fuzz target that will use it:
|
repository, then add a line like this to the options file for the fuzz target
|
||||||
|
that will use it:
|
||||||
|
|
||||||
```
|
```
|
||||||
[libfuzzer]
|
[libfuzzer]
|
||||||
dict = my_dictionary.dict
|
dict = my_dictionary.dict
|
||||||
```
|
```
|
||||||
|
|
||||||
Furthermore, in this directory is a file named `user_settings.h`. The contents
|
Note that dictionaries are found relative to the root directory of this
|
||||||
of this file will be used when compiling wolfSSL in the OSS-Fuzz environment.
|
repository. Do not use relative or absolute paths, simply the name of the file.
|
||||||
It's most important job is to replace the random number generator with a
|
|
||||||
counter so that wolfSSL will behave deterministically.
|
|
||||||
|
|
||||||
### <a name="target_src">Source Code</a>
|
### <a name="target_src">Source Code</a>
|
||||||
|
|
||||||
The source code is more or less what you'd expect: the code describing the
|
The source code is more or less what you'd expect: the code describing the
|
||||||
test. It can be named however you like, though must end with ".c". Internally,
|
test. It must be named `target.c`. Internally, the only requirement is that it
|
||||||
the only requirement is that it not implement `main()` and instead implement a
|
not implement `main()` and instead implement a function for this prototype:
|
||||||
function for this prototype:
|
|
||||||
|
|
||||||
```c
|
```c
|
||||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t sz);
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t sz);
|
||||||
|
@ -178,21 +176,17 @@ the content of a file. If the target was invoked at the command line with file
|
||||||
names, the content of data will be exactly the content of the file. Otherwise,
|
names, the content of data will be exactly the content of the file. Otherwise,
|
||||||
it will contain the fuzzed version of files in the corpus.
|
it will contain the fuzzed version of files in the corpus.
|
||||||
|
|
||||||
From here, all you need to do to accomplish the test is to pass `data` and `sz`
|
From here, `data` and `sz` must become the input of another function. In many
|
||||||
to whatever API call you wish to fuzz. For examples, please see the other fuzz
|
cases, this is as simple as using `data` and `sz` in the function call, but
|
||||||
targets contained in this directory.
|
sometimes creativity must be used to expose the library to the fuzzed data.
|
||||||
|
|
||||||
### <a name="target_opt">Options</a>
|
### <a name="target_opt">Options</a>
|
||||||
|
|
||||||
An options file will indicate to OSS-Fuzz which flags and values to pass to the
|
An options file will indicate to OSS-Fuzz which flags and values to pass to the
|
||||||
fuzz target when running it. It is not required, but it is recommended that you
|
fuzz target when running it. An options file must be named `target.options`.
|
||||||
at least define `max_len`.
|
|
||||||
|
|
||||||
An options file should be named the same as the source code, but with
|
|
||||||
".options" in place of ".c".
|
|
||||||
|
|
||||||
The format seems to be similar to [the ini format][ini], though no explicit
|
The format seems to be similar to [the ini format][ini], though no explicit
|
||||||
confirmation of this was found. Regardless, a file about like this is suitable:
|
confirmation of this was found. For example, a file like this is valid:
|
||||||
|
|
||||||
```
|
```
|
||||||
[libfuzzer]
|
[libfuzzer]
|
||||||
|
@ -208,12 +202,13 @@ recommended that you include a few examples of good input. If ever fuzzing
|
||||||
finds an example of bad input, it is also recommended that you add this bad
|
finds an example of bad input, it is also recommended that you add this bad
|
||||||
input to make sure the problem that created it is not re-introduced.
|
input to make sure the problem that created it is not re-introduced.
|
||||||
|
|
||||||
The corpus must be a directory named the same as the source code, but with
|
The corpus must be a directory. It may have any name, though know that when
|
||||||
`_corpus` in place of ".c".
|
OSS-Fuzz tries to find corpora, it will assume every directory in the target's
|
||||||
|
directory is a corpus.
|
||||||
|
|
||||||
The contents of the corpus do not need to conform to any kind of naming scheme,
|
The contents of the corpus do not need to conform to any kind of naming scheme,
|
||||||
though libFuzzer expects the file's name to be the sha1 sum of the file, and so
|
though libFuzzer is happiest when the file's name is the sha1 sum of the file,
|
||||||
it is recommended that all corpus files are named accordingly.
|
and so it is recommended that all corpus files are named accordingly.
|
||||||
|
|
||||||
<a name="with_oss-fuzz">Running Targets in OSS-Fuzz</a>
|
<a name="with_oss-fuzz">Running Targets in OSS-Fuzz</a>
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
@ -242,13 +237,16 @@ $ git clone https://github.com/google/oss-fuzz
|
||||||
|
|
||||||
Note that if you are going to be modifying the fuzz targets, you'll need to
|
Note that if you are going to be modifying the fuzz targets, you'll need to
|
||||||
modify where Docker will get its targets. Open
|
modify where Docker will get its targets. Open
|
||||||
`./oss-fuzz/projects/wolfssl/Dockerfile` and change the line
|
`./oss-fuzz/projects/wolfssl/Dockerfile` and change this line:
|
||||||
|
|
||||||
```
|
```
|
||||||
RUN git clone --depth 1 https://github.com/wolfssl/wolfssl.git wolfssl
|
RUN git clone --depth 1 https://github.com/wolfssl/wolfssl.git wolfssl
|
||||||
```
|
```
|
||||||
|
|
||||||
to something like this:
|
to something like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
RUN git clone --depth 1 https://github.com/<you>/wolfssl.git -b <work_branch>wolfssl
|
RUN git clone --depth 1 https://github.com/<you>/wolfssl.git -b <work_branch> wolfssl
|
||||||
```
|
```
|
||||||
|
|
||||||
Be sure to replace `<you>` with your github user name and `<work_branch>` with
|
Be sure to replace `<you>` with your github user name and `<work_branch>` with
|
||||||
|
@ -270,20 +268,21 @@ You may also choose to use `memory` or `undefined` for the sanitizer option.
|
||||||
To actually run a fuzz target, run this command:
|
To actually run a fuzz target, run this command:
|
||||||
|
|
||||||
```
|
```
|
||||||
# python infra/helper.py run_fuzzer wolfssl <fuzz_target>
|
# python infra/helper.py run_fuzzer wolfssl fuzz_target
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `<fuzz_target>` corresponds with the file name (without the ".c") of the
|
Where `fuzz_target` stands for the fuzz target you wish to run. The name of the
|
||||||
target you wish to run.
|
fuzz target corresponds with the directory name containing the source code of
|
||||||
|
the target you wish to run.
|
||||||
|
|
||||||
<a name="future">Future Direction</a>
|
<a name="future">Future Direction</a>
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
Add more tests for various wolfSSL and wolfCrypt APIs. Focus on APIs which
|
Add more tests for various wolfSSL and wolfCrypt APIs. Focus on APIs which
|
||||||
process buffers containing data that plausibly could originate from some
|
process buffers containing data that plausibly could originate from some
|
||||||
outside source. As examples, in `server.c` the fuzzed data is impersonating a
|
outside source. It is possible that a target for any given API has already been
|
||||||
server, and in `pem2der.c` the fuzzed data is used as a PEM certificate. In
|
written: check the private wolfssl testing repository for targets before
|
||||||
each case, the fuzzed data represents malformed input.
|
writing them yourself.
|
||||||
|
|
||||||
<!-- References -->
|
<!-- References -->
|
||||||
[libFuzzer]: http://llvm.org/docs/LibFuzzer.html
|
[libFuzzer]: http://llvm.org/docs/LibFuzzer.html
|
||||||
|
|
Loading…
Reference in New Issue