Skip to content

Commit 82be59c

Browse files
committed
Add: fuzz_mmdb to support OSS-Fuzz
Signed-off-by: Arjun <[email protected]>
1 parent 5134712 commit 82be59c

File tree

4 files changed

+84
-0
lines changed

4 files changed

+84
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ if (WIN32)
1313
endif()
1414
option(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" OFF)
1515
option(BUILD_TESTING "Build test programs" ON)
16+
option(BUILD_FUZZING "Build with fuzzer" OFF)
1617
option(MAXMINDDB_BUILD_BINARIES "Build binaries" ON)
1718
option(MAXMINDDB_INSTALL "Generate the install target" ON)
1819

README.fuzzing.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Fuzzing libmaxminddb
2+
3+
These tests are only meant to be run on GNU/Linux.
4+
5+
## Build maxminddb fuzzer using libFuzzer.
6+
7+
### Export flags for fuzzing.
8+
9+
Note that in `CFLAGS` and `CXXFLAGS`, any type of sanitizers can be added.
10+
11+
- [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html),
12+
[ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html),
13+
[MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html),
14+
[UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html),
15+
[LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html).
16+
17+
```shell
18+
$ export CC=clang
19+
$ export CXX=clang++
20+
$ export CFLAGS="-g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address,undefined -fsanitize=fuzzer-no-link"
21+
$ export CXXFLAGS="-g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address,undefined -fsanitize=fuzzer-no-link"
22+
$ export LIB_FUZZING_ENGINE="-fsanitize=fuzzer"
23+
```
24+
25+
### Build maxminddb for fuzzing.
26+
27+
```shell
28+
$ mkdir -p build && cd build
29+
$ cmake -DBUILD_FUZZING=ON ../.
30+
$ cmake --build . -j$(nproc)
31+
```
32+
33+
### Running fuzzer.
34+
35+
```shell
36+
$ mkdir -p fuzz_mmdb_seed fuzz_mmdb_seed_corpus
37+
$ find ../t/maxmind-db/test-data/ -type f -size -4k -exec cp {} ./fuzz_mmdb_seed_corpus/ \;
38+
$ ./t/fuzz_mmdb fuzz_mmdb_seed/ fuzz_mmdb_seed_corpus/
39+
```
40+
41+
Here is more information about [LibFuzzer](https://llvm.org/docs/LibFuzzer.html).

t/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,9 @@ foreach(TEST_TARGET_NAME ${TEST_TARGET_NAMES})
5252

5353
add_test( NAME ${TEST_TARGET_NAME} COMMAND ${TEST_TARGET_NAME} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/t)
5454
endforeach()
55+
56+
if(BUILD_FUZZING)
57+
add_executable(fuzz_mmdb fuzz_mmdb.c)
58+
target_include_directories(fuzz_mmdb PRIVATE ../src)
59+
target_link_libraries(fuzz_mmdb maxminddb $ENV{LIB_FUZZING_ENGINE})
60+
endif()

t/fuzz_mmdb.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include "maxminddb-compat-util.h"
2+
#include "maxminddb.h"
3+
#include <unistd.h>
4+
5+
#define kMinInputLength 2
6+
#define kMaxInputLength 4048
7+
8+
extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
9+
10+
int
11+
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
12+
{
13+
int status;
14+
FILE *fp;
15+
MMDB_s mmdb;
16+
char filename[256];
17+
18+
if (size < kMinInputLength || size > kMaxInputLength)
19+
return 0;
20+
21+
sprintf(filename, "/tmp/libfuzzer.%d", getpid());
22+
23+
fp = fopen(filename, "wb");
24+
if (!fp)
25+
return 0;
26+
27+
fwrite(data, size, sizeof(uint8_t), fp);
28+
fclose(fp);
29+
30+
status = MMDB_open(filename, MMDB_MODE_MMAP, &mmdb);
31+
if (status == MMDB_SUCCESS)
32+
MMDB_close(&mmdb);
33+
34+
unlink(filename);
35+
return 0;
36+
}

0 commit comments

Comments
 (0)