From 08482b59872fe590fbd73981733beebc1e72f51f Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Wed, 14 Dec 2016 14:15:42 -0500 Subject: Update fuzzers with comments from OSS-Fuzz review Add explicit length limitations, to prevent the fuzzer from just giving us increasingly long inputs until timeout occurs due to non-linear algorithms. Use LLVM fuzzer interface in all cases, and just have AFL driver call that API when a define is set to include a main function. OSS-Fuzz will be using the LLVM API, regardless of the fuzzing engine. [ci skip] --- src/extra_tests/fuzzers/GNUmakefile | 9 +++++---- src/extra_tests/fuzzers/jigs/ber_decode.cpp | 3 +++ src/extra_tests/fuzzers/jigs/bn_sqr.cpp | 3 +++ src/extra_tests/fuzzers/jigs/cert.cpp | 3 +++ src/extra_tests/fuzzers/jigs/crl.cpp | 3 +++ src/extra_tests/fuzzers/jigs/divide.cpp | 3 +++ src/extra_tests/fuzzers/jigs/driver.h | 18 ++++++------------ src/extra_tests/fuzzers/jigs/ecc_bp256.cpp | 3 +++ src/extra_tests/fuzzers/jigs/ecc_p256.cpp | 2 ++ src/extra_tests/fuzzers/jigs/ecc_p384.cpp | 2 ++ src/extra_tests/fuzzers/jigs/ecc_p521.cpp | 2 ++ src/extra_tests/fuzzers/jigs/invert.cpp | 3 +++ src/extra_tests/fuzzers/jigs/os2ecp.cpp | 3 +++ src/extra_tests/fuzzers/jigs/redc_p192.cpp | 3 +++ src/extra_tests/fuzzers/jigs/redc_p256.cpp | 3 +++ src/extra_tests/fuzzers/jigs/redc_p384.cpp | 3 +++ src/extra_tests/fuzzers/jigs/redc_p521.cpp | 3 +++ src/extra_tests/fuzzers/jigs/ressol.cpp | 4 ++-- src/extra_tests/fuzzers/readme.txt | 2 +- 19 files changed, 56 insertions(+), 19 deletions(-) (limited to 'src/extra_tests/fuzzers') diff --git a/src/extra_tests/fuzzers/GNUmakefile b/src/extra_tests/fuzzers/GNUmakefile index daa5c7a37..43866d0c3 100644 --- a/src/extra_tests/fuzzers/GNUmakefile +++ b/src/extra_tests/fuzzers/GNUmakefile @@ -3,11 +3,12 @@ FUZZERS=$(patsubst jigs/%.cpp,%,$(wildcard jigs/*.cpp)) AFL_SAN_FLAGS=-fsanitize=address,undefined -fno-sanitize-recover=undefined CLANG_SAN_FLAGS=-fsanitize=address,undefined -fno-sanitize-recover=undefined -fsanitize-coverage=edge,indirect-calls,8bit-counters +CLANG_SAN_FLAGS=-fsanitize-coverage=edge,indirect-calls,8bit-counters -CFG_FLAGS=--enable-debug --unsafe-fuzzer-mode +CFG_FLAGS=--with-debug-info --unsafe-fuzzer-mode SHARED_FLAGS=-O3 -g -std=c++11 -pthread -LIBFUZZER_FLAGS=-DUSE_LLVM_FUZZER -Illvm-build/build/include $(SHARED_FLAGS) $(CLANG_SAN_FLAGS) -AFL_FLAGS=-Iafl-build/build/include $(SHARED_FLAGS) +LIBFUZZER_FLAGS=-Illvm-build/build/include $(SHARED_FLAGS) $(CLANG_SAN_FLAGS) +AFL_FLAGS=-DINCLUDE_AFL_MAIN -Iafl-build/build/include $(SHARED_FLAGS) LIBFUZZER_LIBS=llvm-build/libbotan-1.11.a libFuzzer.a AFL_LIBS=afl-build/libbotan-1.11.a @@ -28,7 +29,7 @@ afl: dirs afl-build $(AFL_PROGS) llvm: dirs llvm-build $(LIBFUZZER_PROGS) bin/llvm_fuzz_%: jigs/%.cpp $(LIBFUZZER_LIBS) - $(CLANG_CXX) $(LIBFUZZER_FLAGS) -DUSE_LLVM_FUZZER $< $(LIBFUZZER_LIBS) -o $@ + $(CLANG_CXX) $(LIBFUZZER_FLAGS) $< $(LIBFUZZER_LIBS) -o $@ bin/afl_fuzz_%: jigs/%.cpp $(AFL_LIBS) $(AFL_CXX) $(AFL_FLAGS) $< $(AFL_LIBS) -o $@ diff --git a/src/extra_tests/fuzzers/jigs/ber_decode.cpp b/src/extra_tests/fuzzers/jigs/ber_decode.cpp index 0f5cc9f20..6ec9cadba 100644 --- a/src/extra_tests/fuzzers/jigs/ber_decode.cpp +++ b/src/extra_tests/fuzzers/jigs/ber_decode.cpp @@ -9,6 +9,9 @@ void fuzz(const uint8_t in[], size_t len) { + if(len > 4096) + return; + try { DataSource_Memory input(in, len); diff --git a/src/extra_tests/fuzzers/jigs/bn_sqr.cpp b/src/extra_tests/fuzzers/jigs/bn_sqr.cpp index 2bc5ebe33..aa76067f7 100644 --- a/src/extra_tests/fuzzers/jigs/bn_sqr.cpp +++ b/src/extra_tests/fuzzers/jigs/bn_sqr.cpp @@ -11,6 +11,9 @@ void fuzz(const uint8_t in[], size_t len) { + if(len > 8192/8) + return; + Botan::BigInt x = Botan::BigInt::decode(in, len); Botan::BigInt x_sqr = square(x); diff --git a/src/extra_tests/fuzzers/jigs/cert.cpp b/src/extra_tests/fuzzers/jigs/cert.cpp index 2c13551e2..5620a4700 100644 --- a/src/extra_tests/fuzzers/jigs/cert.cpp +++ b/src/extra_tests/fuzzers/jigs/cert.cpp @@ -9,6 +9,9 @@ void fuzz(const uint8_t in[], size_t len) { + if(len > 8192) + return; + try { DataSource_Memory input(in, len); diff --git a/src/extra_tests/fuzzers/jigs/crl.cpp b/src/extra_tests/fuzzers/jigs/crl.cpp index be61ae131..b3157e5fe 100644 --- a/src/extra_tests/fuzzers/jigs/crl.cpp +++ b/src/extra_tests/fuzzers/jigs/crl.cpp @@ -9,6 +9,9 @@ void fuzz(const uint8_t in[], size_t len) { + if(len > 4096) + return; + try { DataSource_Memory input(in, len); diff --git a/src/extra_tests/fuzzers/jigs/divide.cpp b/src/extra_tests/fuzzers/jigs/divide.cpp index fba68b9a6..4ff50a680 100644 --- a/src/extra_tests/fuzzers/jigs/divide.cpp +++ b/src/extra_tests/fuzzers/jigs/divide.cpp @@ -8,6 +8,9 @@ void fuzz(const uint8_t in[], size_t len) { + if(len % 2 == 1 || len > 2*4096/8) + return; + const BigInt x = BigInt::decode(in, len / 2); const BigInt y = BigInt::decode(in + len / 2, len / 2); diff --git a/src/extra_tests/fuzzers/jigs/driver.h b/src/extra_tests/fuzzers/jigs/driver.h index 3eab8623d..bac0f572b 100644 --- a/src/extra_tests/fuzzers/jigs/driver.h +++ b/src/extra_tests/fuzzers/jigs/driver.h @@ -17,32 +17,26 @@ using namespace Botan; -void fuzz(const uint8_t in[], size_t len); +extern void fuzz(const uint8_t in[], size_t len); -void fuzzer_init() +extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) { /* * This disables the mlock pool, as overwrites within the pool are * opaque to ASan or other instrumentation. */ ::setenv("BOTAN_MLOCK_POOL_SIZE", "0", 1); + return 0; } -#if defined(USE_LLVM_FUZZER) - -// Called by main() in libFuzzer +// Called by main() in libFuzzer or in main for AFL below extern "C" int LLVMFuzzerTestOneInput(const uint8_t in[], size_t len) { fuzz(in, len); return 0; } -int LLVMFuzzerInitialize(int *argc, char ***argv) { - fuzzer_init(); - return 0; -} - -#else +#if defined(INCLUDE_AFL_MAIN) // Read stdin for AFL @@ -50,7 +44,7 @@ int main(int argc, char* argv[]) { const size_t max_read = 4096; - fuzzer_init(); + LLVMFuzzerInitialize(); #if defined(__AFL_LOOP) while(__AFL_LOOP(1000)) diff --git a/src/extra_tests/fuzzers/jigs/ecc_bp256.cpp b/src/extra_tests/fuzzers/jigs/ecc_bp256.cpp index 5b979b03f..07833c639 100644 --- a/src/extra_tests/fuzzers/jigs/ecc_bp256.cpp +++ b/src/extra_tests/fuzzers/jigs/ecc_bp256.cpp @@ -8,6 +8,9 @@ void fuzz(const uint8_t in[], size_t len) { + if(len > 2*256/8) + return; + static EC_Group bp256("brainpool256r1"); return check_ecc_math(bp256, in, len); } diff --git a/src/extra_tests/fuzzers/jigs/ecc_p256.cpp b/src/extra_tests/fuzzers/jigs/ecc_p256.cpp index 429925ba1..f13104fda 100644 --- a/src/extra_tests/fuzzers/jigs/ecc_p256.cpp +++ b/src/extra_tests/fuzzers/jigs/ecc_p256.cpp @@ -8,6 +8,8 @@ void fuzz(const uint8_t in[], size_t len) { + if(len > 2*256/8) + return; static EC_Group p256("secp256r1"); return check_ecc_math(p256, in, len); } diff --git a/src/extra_tests/fuzzers/jigs/ecc_p384.cpp b/src/extra_tests/fuzzers/jigs/ecc_p384.cpp index 0441b6dcf..47826e1d6 100644 --- a/src/extra_tests/fuzzers/jigs/ecc_p384.cpp +++ b/src/extra_tests/fuzzers/jigs/ecc_p384.cpp @@ -8,6 +8,8 @@ void fuzz(const uint8_t in[], size_t len) { + if(len > 2*384/8) + return; static EC_Group p384("secp384r1"); return check_ecc_math(p384, in, len); } diff --git a/src/extra_tests/fuzzers/jigs/ecc_p521.cpp b/src/extra_tests/fuzzers/jigs/ecc_p521.cpp index cc998137c..c2d1e36bb 100644 --- a/src/extra_tests/fuzzers/jigs/ecc_p521.cpp +++ b/src/extra_tests/fuzzers/jigs/ecc_p521.cpp @@ -8,6 +8,8 @@ void fuzz(const uint8_t in[], size_t len) { + if(len > 2*(521+7)/8) + return; static EC_Group p521("secp521r1"); return check_ecc_math(p521, in, len); } diff --git a/src/extra_tests/fuzzers/jigs/invert.cpp b/src/extra_tests/fuzzers/jigs/invert.cpp index fcda5770e..63c140139 100644 --- a/src/extra_tests/fuzzers/jigs/invert.cpp +++ b/src/extra_tests/fuzzers/jigs/invert.cpp @@ -51,6 +51,9 @@ BigInt inverse_mod_ref(const BigInt& n, const BigInt& mod) void fuzz(const uint8_t in[], size_t len) { + if(len % 2 == 1 || len > 2*4096/8) + return; + const BigInt x = BigInt::decode(in, len / 2); BigInt mod = BigInt::decode(in + len / 2, len / 2); diff --git a/src/extra_tests/fuzzers/jigs/os2ecp.cpp b/src/extra_tests/fuzzers/jigs/os2ecp.cpp index 2b939eb5b..61ce1bd7b 100644 --- a/src/extra_tests/fuzzers/jigs/os2ecp.cpp +++ b/src/extra_tests/fuzzers/jigs/os2ecp.cpp @@ -18,6 +18,9 @@ void check_os2ecp(const EC_Group& group, const uint8_t in[], size_t len) void fuzz(const uint8_t in[], size_t len) { + if(len >= 256) + return; + static EC_Group p192("secp192r1"); static EC_Group p224("secp224r1"); static EC_Group p256("secp256r1"); diff --git a/src/extra_tests/fuzzers/jigs/redc_p192.cpp b/src/extra_tests/fuzzers/jigs/redc_p192.cpp index a27e6a37b..9bece4595 100644 --- a/src/extra_tests/fuzzers/jigs/redc_p192.cpp +++ b/src/extra_tests/fuzzers/jigs/redc_p192.cpp @@ -10,6 +10,9 @@ void fuzz(const uint8_t in[], size_t len) { + if(len > 2*192/8) + return; + static const BigInt& prime = Botan::prime_p192(); static const BigInt prime_2 = prime * prime; static Botan::Modular_Reducer prime_redc(prime); diff --git a/src/extra_tests/fuzzers/jigs/redc_p256.cpp b/src/extra_tests/fuzzers/jigs/redc_p256.cpp index 86f0910a0..cbb7f4fef 100644 --- a/src/extra_tests/fuzzers/jigs/redc_p256.cpp +++ b/src/extra_tests/fuzzers/jigs/redc_p256.cpp @@ -10,6 +10,9 @@ void fuzz(const uint8_t in[], size_t len) { + if(len > 2*256/8) + return; + static const BigInt& prime = Botan::prime_p256(); static const BigInt prime_2 = prime * prime; static Botan::Modular_Reducer prime_redc(prime); diff --git a/src/extra_tests/fuzzers/jigs/redc_p384.cpp b/src/extra_tests/fuzzers/jigs/redc_p384.cpp index 9a9ac896a..3b990fb63 100644 --- a/src/extra_tests/fuzzers/jigs/redc_p384.cpp +++ b/src/extra_tests/fuzzers/jigs/redc_p384.cpp @@ -10,6 +10,9 @@ void fuzz(const uint8_t in[], size_t len) { + if(len > 2*384/8) + return; + static const BigInt& prime = Botan::prime_p384(); static const BigInt prime_2 = prime * prime; static Botan::Modular_Reducer prime_redc(prime); diff --git a/src/extra_tests/fuzzers/jigs/redc_p521.cpp b/src/extra_tests/fuzzers/jigs/redc_p521.cpp index fe164217d..5142a44c2 100644 --- a/src/extra_tests/fuzzers/jigs/redc_p521.cpp +++ b/src/extra_tests/fuzzers/jigs/redc_p521.cpp @@ -10,6 +10,9 @@ void fuzz(const uint8_t in[], size_t len) { + if(len > 2*(521+7)/8) + return; + static const BigInt& prime = Botan::prime_p521(); static const BigInt prime_2 = prime * prime; static Botan::Modular_Reducer prime_redc(prime); diff --git a/src/extra_tests/fuzzers/jigs/ressol.cpp b/src/extra_tests/fuzzers/jigs/ressol.cpp index 3f7f82502..97130255c 100644 --- a/src/extra_tests/fuzzers/jigs/ressol.cpp +++ b/src/extra_tests/fuzzers/jigs/ressol.cpp @@ -39,9 +39,9 @@ void fuzz(const uint8_t in[], size_t len) if(is_prime(n, fuzzer_rng(), 64)) { std::cout << "A = " << a << "\n"; - std::cout << "Ressol = " << a_sqrt << "\n"; std::cout << "N = " << n << "\n"; - std::cout << "Z = " << z << "\n"; + std::cout << "Ressol = " << a_sqrt << "\n"; + std::cout << "recomputed = " << z << "\n"; abort(); } } diff --git a/src/extra_tests/fuzzers/readme.txt b/src/extra_tests/fuzzers/readme.txt index e195b4e70..1bee1a785 100644 --- a/src/extra_tests/fuzzers/readme.txt +++ b/src/extra_tests/fuzzers/readme.txt @@ -16,7 +16,7 @@ and implement the function with the signature void fuzz(const uint8_t buf[], size_t len); -This function should abort or crash if something is incorrect. +This function should abort/crash if something is incorrect. Run it with -- cgit v1.2.3