Add libFuzzer integration + report bug
This commit places the basics for libFuzzer integration with one fuzzer which fuzzes the readMetadata function. The fuzzer is located at fuzz/read-metadata. To add more fuzzers please add them to ./fuzz directory as described in the README. Also a memory corruption bug is found using this fuzzer which might lead to additional bugs after fix is pushed.
This commit is contained in:
parent
c7757d7c08
commit
b2cdf2a535
@ -35,6 +35,7 @@ option( EXIV2_ENABLE_BMFF "Build with BMFF support"
|
|||||||
option( EXIV2_BUILD_SAMPLES "Build sample applications" ON )
|
option( EXIV2_BUILD_SAMPLES "Build sample applications" ON )
|
||||||
option( EXIV2_BUILD_EXIV2_COMMAND "Build exiv2 command-line executable" ON )
|
option( EXIV2_BUILD_EXIV2_COMMAND "Build exiv2 command-line executable" ON )
|
||||||
option( EXIV2_BUILD_UNIT_TESTS "Build unit tests" OFF )
|
option( EXIV2_BUILD_UNIT_TESTS "Build unit tests" OFF )
|
||||||
|
option( EXIV2_BUILD_FUZZ_TESTS "Build fuzz tests (libFuzzer)" OFF )
|
||||||
option( EXIV2_BUILD_DOC "Add 'doc' target to generate documentation" OFF )
|
option( EXIV2_BUILD_DOC "Add 'doc' target to generate documentation" OFF )
|
||||||
|
|
||||||
# Only intended to be used by Exiv2 developers/contributors
|
# Only intended to be used by Exiv2 developers/contributors
|
||||||
@ -91,6 +92,14 @@ if( EXIV2_BUILD_UNIT_TESTS )
|
|||||||
add_subdirectory ( unitTests )
|
add_subdirectory ( unitTests )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if( EXIV2_BUILD_FUZZ_TESTS)
|
||||||
|
if ((NOT COMPILER_IS_CLANG) OR (NOT EXIV2_TEAM_USE_SANITIZERS))
|
||||||
|
message(FATAL_ERROR "You need to build with Clang and sanitizers for the fuzzers to work. "
|
||||||
|
"Use Clang and -DEXIV2_TEAM_USE_SANITIZERS=ON")
|
||||||
|
endif()
|
||||||
|
add_subdirectory ( fuzz )
|
||||||
|
endif()
|
||||||
|
|
||||||
if( EXIV2_BUILD_SAMPLES )
|
if( EXIV2_BUILD_SAMPLES )
|
||||||
add_subdirectory( samples )
|
add_subdirectory( samples )
|
||||||
get_directory_property(SAMPLES DIRECTORY samples DEFINITION APPLICATIONS)
|
get_directory_property(SAMPLES DIRECTORY samples DEFINITION APPLICATIONS)
|
||||||
|
|||||||
24
README.md
24
README.md
@ -64,6 +64,7 @@ The file ReadMe.txt in a build bundle describes how to install the library on th
|
|||||||
3. [Unit tests](#4-3)
|
3. [Unit tests](#4-3)
|
||||||
4. [Python tests](#4-4)
|
4. [Python tests](#4-4)
|
||||||
5. [Test Summary](#4-5)
|
5. [Test Summary](#4-5)
|
||||||
|
6. [Fuzzing](#4-6)
|
||||||
5. [Platform Notes](#5)
|
5. [Platform Notes](#5)
|
||||||
1. [Linux](#5-1)
|
1. [Linux](#5-1)
|
||||||
2. [macOS](#5-2)
|
2. [macOS](#5-2)
|
||||||
@ -1039,6 +1040,29 @@ $ cd <exiv2dir>/build
|
|||||||
$ make python_tests 2>&1 | grep FAIL
|
$ make python_tests 2>&1 | grep FAIL
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 4.6 Fuzzing
|
||||||
|
|
||||||
|
The code for the fuzzers is in `exiv2dir/fuzz`
|
||||||
|
|
||||||
|
To build the fuzzers, use the *cmake* option `-DEXIV2_BUILD_FUZZ_TESTS=ON` and `-DEXIV2_TEAM_USE_SANITIZERS=ON`.
|
||||||
|
Note that it only works with clang compiler as libFuzzer is integrate with clang > 6.0
|
||||||
|
|
||||||
|
To build the fuzzers:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ cd <exiv2dir>
|
||||||
|
$ rm -rf build-fuzz ; mkdir build-fuzz ; cd build-fuzz
|
||||||
|
$ cmake .. -DCMAKE_CXX_COMPILER=$(which clang++) -DEXIV2_BUILD_FUZZ_TESTS=ON -DEXIV2_TEAM_USE_SANITIZERS=ON
|
||||||
|
$ cmake --build .
|
||||||
|
```
|
||||||
|
|
||||||
|
To execute the fuzzers:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd <exiv2dir>/build-fuzz
|
||||||
|
bin/<fuzzer_name> # for example ./bin/read-metadata.cpp
|
||||||
|
```
|
||||||
|
|
||||||
[TOC](#TOC)
|
[TOC](#TOC)
|
||||||
<div id="4-5">
|
<div id="4-5">
|
||||||
|
|
||||||
|
|||||||
@ -66,6 +66,7 @@ endif()
|
|||||||
OptionOutput( "Building exiv2 command: " EXIV2_BUILD_EXIV2_COMMAND )
|
OptionOutput( "Building exiv2 command: " EXIV2_BUILD_EXIV2_COMMAND )
|
||||||
OptionOutput( "Building samples: " EXIV2_BUILD_SAMPLES )
|
OptionOutput( "Building samples: " EXIV2_BUILD_SAMPLES )
|
||||||
OptionOutput( "Building unit tests: " EXIV2_BUILD_UNIT_TESTS )
|
OptionOutput( "Building unit tests: " EXIV2_BUILD_UNIT_TESTS )
|
||||||
|
OptionOutput( "Building fuzz tests: " EXIV2_BUILD_FUZZ_TESTS )
|
||||||
OptionOutput( "Building doc: " EXIV2_BUILD_DOC )
|
OptionOutput( "Building doc: " EXIV2_BUILD_DOC )
|
||||||
OptionOutput( "Building with coverage flags: " BUILD_WITH_COVERAGE )
|
OptionOutput( "Building with coverage flags: " BUILD_WITH_COVERAGE )
|
||||||
OptionOutput( "Using ccache: " BUILD_WITH_CCACHE )
|
OptionOutput( "Using ccache: " BUILD_WITH_CCACHE )
|
||||||
|
|||||||
14
fuzz/CMakeLists.txt
Normal file
14
fuzz/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
macro(fuzzer name)
|
||||||
|
add_executable(${name} ${name}.cpp)
|
||||||
|
set_target_properties(${name}
|
||||||
|
PROPERTIES
|
||||||
|
COMPILE_FLAGS "-fsanitize=fuzzer"
|
||||||
|
LINK_FLAGS "-fsanitize=fuzzer")
|
||||||
|
target_link_libraries(${name}
|
||||||
|
PRIVATE
|
||||||
|
exiv2lib
|
||||||
|
)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
fuzzer(read-metadata)
|
||||||
24
fuzz/read-metadata.cpp
Normal file
24
fuzz/read-metadata.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include <exiv2/exiv2.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t * Data, size_t Size)
|
||||||
|
try {
|
||||||
|
Exiv2::Image::UniquePtr image = Exiv2::ImageFactory::open(Data, Size);
|
||||||
|
assert(image.get() != 0);
|
||||||
|
image->readMetadata();
|
||||||
|
|
||||||
|
Exiv2::ExifData &exifData = image->exifData();
|
||||||
|
if (exifData.empty()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (Exiv2::Error& e) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user