solidity/test/tools/ossfuzz
2023-08-11 14:15:56 +02:00
..
config Update solidity dictionary with TestReader syntax. 2021-02-08 11:16:11 +01:00
protomutators Permit control flow mutations in global scope of a Yul program. 2022-03-14 15:04:32 +01:00
abiV2Proto.proto Permit multiple indirections in coding calldata to and from memory/calldata. 2022-08-12 09:33:06 +02:00
abiV2ProtoFuzzer.cpp Permit multiple indirections in coding calldata to and from memory/calldata. 2022-08-12 09:33:06 +02:00
AbiV2IsabelleFuzzer.cpp Permit multiple indirections in coding calldata to and from memory/calldata. 2022-08-12 09:33:06 +02:00
CMakeLists.txt Silence integer precision loss warning for protobuf fuzzers. 2022-10-12 12:10:43 +02:00
const_opt_ossfuzz.cpp Enable more C++ compiler warnings 2020-12-10 21:03:58 +00:00
Generators.h Solidity fuzzer: Add simple import statements. 2021-02-03 17:03:57 +01:00
protoToAbiV2.cpp docs: fix typos 2022-12-25 22:39:50 +01:00
protoToAbiV2.h updated protoToAbiv2.h 2023-07-09 01:45:54 +02:00
protoToSol.cpp Add SPDX license identifier if not present already in source file 2020-07-17 20:24:12 +05:30
protoToSol.h Enable the -Wconversion warning 2020-12-08 16:45:24 +00:00
protoToYul.cpp Stack optimizer fuzzer: Detect stack-too-deep during optimization 2023-06-27 10:32:23 +02:00
protoToYul.h Stack optimizer fuzzer: Detect stack-too-deep during optimization 2023-06-27 10:32:23 +02:00
README.md Update ubuntu ossfuzz references 2023-04-19 00:18:11 +02:00
solc_ossfuzz.cpp Unify solc fuzzers. 2021-02-08 11:14:38 +01:00
SolidityCustomMutatorInterface.cpp Fuzzer: Refactor utility methods shared by proto fuzzers. 2021-02-10 11:43:57 +01:00
SolidityCustomMutatorInterface.h Fuzzer: Refactor utility methods shared by proto fuzzers. 2021-02-10 11:43:57 +01:00
SolidityEvmoneInterface.cpp SourceReferenceFormatter: Support full range of options in formatErrorInformation() 2023-08-11 14:15:56 +02:00
SolidityEvmoneInterface.h Update EVMHost to match EVMC10 changes 2022-11-09 21:27:40 +01:00
SolidityGenerator.cpp Fuzzer: Refactor utility methods shared by proto fuzzers. 2021-02-10 11:43:57 +01:00
SolidityGenerator.h Fuzzer: Refactor utility methods shared by proto fuzzers. 2021-02-10 11:43:57 +01:00
solProto.proto Add SPDX license identifier if not present already in source file 2020-07-17 20:24:12 +05:30
solProtoFuzzer.cpp Permit multiple indirections in coding calldata to and from memory/calldata. 2022-08-12 09:33:06 +02:00
StackReuseCodegenFuzzer.cpp Stack optimizer fuzzer: Detect stack-too-deep during optimization 2023-06-27 10:32:23 +02:00
strictasm_assembly_ossfuzz.cpp Strict assembly fuzzer: Change optimization setting from full to minimal. 2023-02-24 22:42:07 +01:00
strictasm_diff_ossfuzz.cpp Add experimental EOF options for CLI and Standard JSON. 2022-11-23 19:53:44 +01:00
strictasm_opt_ossfuzz.cpp Add experimental EOF options for CLI and Standard JSON. 2022-11-23 19:53:44 +01:00
YulEvmoneInterface.cpp Stack optimizer fuzzer: Detect stack-too-deep during optimization 2023-06-27 10:32:23 +02:00
YulEvmoneInterface.h Stack optimizer fuzzer: Detect stack-too-deep during optimization 2023-06-27 10:32:23 +02:00
yulFuzzerCommon.cpp YulRunner: Add support for external calls to the same contract 2022-09-14 11:40:02 +02:00
yulFuzzerCommon.h Yul interpreter: Add flag to disable memory tracing and dump for fuzzing. 2022-01-04 11:56:27 +01:00
yulOptimizerFuzzDictionary.h Do not create duplicate case statements 2019-08-26 12:44:06 +02:00
yulProto_diff_ossfuzz.cpp Use printErrorInformation() over printExceptionInformation() where possible 2023-08-11 14:15:56 +02:00
yulProto.proto Add basic support for the EVM version Paris 2022-11-21 14:56:46 +01:00
yulProtoFuzzer.cpp Add experimental EOF options for CLI and Standard JSON. 2022-11-23 19:53:44 +01:00

Intro

oss-fuzz is Google's fuzzing infrastructure that performs continuous fuzzing. What this means is that, each and every upstream commit is automatically fetched by the infrastructure and fuzzed on a daily basis.

How to build fuzzers?

We have multiple fuzzers, some based on string input and others on protobuf input. To build them, please do the following:

  • Create a local docker image from Dockerfile.ubuntu.clang.ossfuzz in the .circleci/docker sub-directory. Please note that this step is likely to take at least an hour to complete. Therefore, it is recommended to do it when you are away from the computer (and the computer is plugged to power since we do not want a battery drain).
$ cd .circleci/docker
$ docker build -t solidity-ossfuzz-local -f Dockerfile.ubuntu.clang.ossfuzz .
  • Login to the docker container sourced from the image built in the previous step from the solidity parent directory
## Host
$ cd solidity
$ docker run -v `pwd`:/src/solidity -ti solidity-ossfuzz-local /bin/bash
## Docker shell
$ cd /src/solidity
  • Run cmake and build fuzzer harnesses
## Docker shell
$ cd /src/solidity
$ rm -rf fuzzer-build && mkdir fuzzer-build && cd fuzzer-build
## Compile protobuf C++ bindings
$ protoc --proto_path=../test/tools/ossfuzz yulProto.proto --cpp_out=../test/tools/ossfuzz
$ protoc --proto_path=../test/tools/ossfuzz abiV2Proto.proto --cpp_out=../test/tools/ossfuzz
## Run cmake
$ export CC=clang CXX=clang++
$ cmake -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/libfuzzer.cmake -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE:-Release} ..
$ make ossfuzz ossfuzz_proto ossfuzz_abiv2 -j

Why the elaborate docker image to build fuzzers?

For the following reasons:

  • Fuzzing binaries must link against libc++ and not libstdc++

    • This is because (1) MemorySanitizer (which flags uses of uninitialized memory) depends on libc++; and (2) because libc++ is instrumented (to check for memory and type errors) and libstdc++ not, the former may find more bugs.
  • Linking against libc++ requires us to compile everything solidity depends on from source (and link these against libc++ as well)

  • To reproduce the compiler versions used by upstream oss-fuzz bots, we need to reuse their docker image containing the said compiler versions

  • Some fuzzers depend on libprotobuf, libprotobuf-mutator, libevmone etc. which may not be available locally; even if they were they might not be the right versions

What is LIB_FUZZING_ENGINE?

oss-fuzz contains multiple fuzzer back-ends i.e., fuzzers. Each back-end may require different linker flags. oss-fuzz builder bot defines the correct linker flags via a bash environment variable called LIB_FUZZING_ENGINE.

For the solidity ossfuzz CI build, we use the libFuzzer back-end. This back-end requires us to manually set the LIB_FUZZING_ENGINE to -fsanitize=fuzzer.

What does the ossfuzz directory contain?

To help oss-fuzz do this, we (as project maintainers) need to provide the following:

  • test harnesses: C/C++ tests that define the LLVMFuzzerTestOneInput API. This determines what is to be fuzz tested.
  • build infrastructure: (c)make targets per fuzzing binary. Fuzzing requires coverage and memory instrumentation of the code to be fuzzed.
  • configuration files: These are files with the .options extension that are parsed by oss-fuzz. The only option that we use currently is the dictionary option that asks the fuzzing engines behind oss-fuzz to use the specified dictionary. The specified dictionary happens to be solidity.dict.

solidity.dict contains Solidity-specific syntactical tokens that are more likely to guide the fuzzer towards generating parseable and varied Solidity input.

To be consistent and aid better evaluation of the utility of the fuzzing dictionary, we stick to the following rules-of-thumb:

  • Full tokens such as block.number are preceded and followed by a whitespace
  • Incomplete tokens including function calls such as msg.sender.send() are abbreviated .send( to provide some leeway to the fuzzer to sythesize variants such as address(this).send()
  • Language keywords are suffixed by a whitespace with the exception of those that end a line of code such as break; and continue;