diff --git a/config/with-llvm-cov.mk b/config/with-llvm-cov.mk index 265b73ea20..f95685ae29 100644 --- a/config/with-llvm-cov.mk +++ b/config/with-llvm-cov.mk @@ -2,6 +2,9 @@ ifneq "$(FD_USING_CLANG)" "1" $(error llvm-cov requires clang) endif +FD_HAS_COVERAGE:=1 + +CPPFLAGS+=-DFD_HAS_COVERAGE=1 CPPFLAGS+=-fprofile-instr-generate -fcoverage-mapping LDFLAGS+=-fprofile-instr-generate -fcoverage-mapping diff --git a/src/ballet/base58/fuzz_base58_garbage.c b/src/ballet/base58/fuzz_base58_garbage.c index 6510fdf346..b7107a71f8 100644 --- a/src/ballet/base58/fuzz_base58_garbage.c +++ b/src/ballet/base58/fuzz_base58_garbage.c @@ -6,6 +6,7 @@ #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_base58.h" int @@ -45,16 +46,21 @@ LLVMFuzzerTestOneInput( uchar const * data, do { uchar out[32]; - if( fd_base58_decode_32( cstr, out ) ) + if( fd_base58_decode_32( cstr, out ) ) { + FD_FUZZ_MUST_BE_COVERED; touch( out, sizeof(out) ); + } } while(0); do { uchar out[64]; - if( fd_base58_decode_64( cstr, out ) ) + if( fd_base58_decode_64( cstr, out ) ) { + FD_FUZZ_MUST_BE_COVERED; touch( out, sizeof(out) ); + } } while(0); free( cstr ); + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/base58/fuzz_base58_roundtrip.c b/src/ballet/base58/fuzz_base58_roundtrip.c index 1d42fedc1e..0b2c47de31 100644 --- a/src/ballet/base58/fuzz_base58_roundtrip.c +++ b/src/ballet/base58/fuzz_base58_roundtrip.c @@ -2,10 +2,12 @@ #error "This target requires FD_HAS_HOSTED" #endif +#include #include #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_base58.h" int @@ -28,31 +30,18 @@ LLVMFuzzerTestOneInput( uchar const * data, char enc##n [ FD_BASE58_ENCODED_##n##_SZ ]; \ char enc##n##_nolen[ FD_BASE58_ENCODED_##n##_SZ ]; \ uchar dec##n [ n ]; \ - if( FD_UNLIKELY( fd_base58_encode_##n( data, &len##n, enc##n )!=enc##n ) ) { \ - __builtin_trap(); \ - } \ - if( FD_UNLIKELY( strlen( enc##n )!=len##n ) ) { \ - __builtin_trap(); \ - } \ - if( FD_UNLIKELY( len##nFD_BASE58_ENCODED_##n##_LEN ) ) { \ - __builtin_trap(); \ - } \ - if( FD_UNLIKELY( fd_base58_decode_##n( enc##n, dec##n )!=dec##n ) ) { \ - __builtin_trap(); \ - } \ - if( FD_UNLIKELY( memcmp( dec##n, data, n##UL ) ) ) { \ - __builtin_trap(); \ - } \ - if( FD_UNLIKELY( fd_base58_encode_##n( data, NULL, enc##n##_nolen )!=enc##n##_nolen ) ) { \ - __builtin_trap(); \ - } \ - if( FD_UNLIKELY( strcmp( enc##n##_nolen, enc##n ) ) ) { \ - __builtin_trap(); \ - } + assert( fd_base58_encode_##n( data, &len##n, enc##n ) == enc##n ); \ + assert( strlen( enc##n ) == len##n ); \ + assert( len##n>=n##UL && len##n <= FD_BASE58_ENCODED_##n##_LEN ); \ + assert( fd_base58_decode_##n( enc##n, dec##n ) == dec##n ); \ + assert( !memcmp( dec##n, data, n##UL ) ); \ + assert( fd_base58_encode_##n( data, NULL, enc##n##_nolen ) == enc##n##_nolen ); \ + assert( !strcmp( enc##n##_nolen, enc##n ) ); MAKE_FUZZ_TEST(32) MAKE_FUZZ_TEST(64) #undef MAKE_FUZZ_TEST + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/base64/fuzz_base64_dec.c b/src/ballet/base64/fuzz_base64_dec.c index f39292c5dc..cbe4f2d6a2 100644 --- a/src/ballet/base64/fuzz_base64_dec.c +++ b/src/ballet/base64/fuzz_base64_dec.c @@ -7,6 +7,7 @@ #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_base64.h" /* fuzz_base64_dec verifies that Base64 decoding is safe against @@ -33,8 +34,15 @@ LLVMFuzzerTestOneInput( uchar const * data, assert( dec ); long dec_res = fd_base64_decode( dec, (char const *)data, data_sz ); - assert( dec_res>=0L || dec_res==-1L ); + if ( dec_res>=0L ) { + FD_FUZZ_MUST_BE_COVERED; + } else if ( dec_res==-1L ) { + FD_FUZZ_MUST_BE_COVERED; + } else { + abort(); + } free( dec ); + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/base64/fuzz_base64_enc.c b/src/ballet/base64/fuzz_base64_enc.c index 6967d54efa..a871cee1b6 100644 --- a/src/ballet/base64/fuzz_base64_enc.c +++ b/src/ballet/base64/fuzz_base64_enc.c @@ -7,6 +7,8 @@ #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" + #include "fd_base64.h" /* fuzz_base64_enc verifies that decode(encode(x)) is the identity @@ -48,5 +50,6 @@ LLVMFuzzerTestOneInput( uchar const * data, free( enc ); free( dec ); + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/blake3/fuzz_blake3.c b/src/ballet/blake3/fuzz_blake3.c index 6d2c741a51..c313dec745 100644 --- a/src/ballet/blake3/fuzz_blake3.c +++ b/src/ballet/blake3/fuzz_blake3.c @@ -2,10 +2,12 @@ #error "This target requires FD_HAS_HOSTED" #endif +#include #include #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_blake3.h" int @@ -28,29 +30,14 @@ LLVMFuzzerTestOneInput( uchar const * data, uchar hash2[ 32 ] __attribute__((aligned(32))); fd_blake3_t sha[1]; - if( FD_UNLIKELY( fd_blake3_init( sha )!=sha ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( fd_blake3_append( sha, msg, size )!=sha ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( fd_blake3_fini( sha, hash1 )!=hash1 ) ) { - __builtin_trap(); - } - - if( FD_UNLIKELY( fd_blake3_init( sha )!=sha ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( fd_blake3_append( sha, msg, size )!=sha ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( fd_blake3_fini( sha, hash2 )!=hash2 ) ) { - __builtin_trap(); - } - - if( FD_UNLIKELY( memcmp( hash1, hash2, 32UL ) ) ) { - __builtin_trap(); - } - + assert( fd_blake3_init( sha ) == sha ); + assert( fd_blake3_append( sha, msg, size ) == sha ); + assert( fd_blake3_fini( sha, hash1 ) == hash1 ); + assert( fd_blake3_init( sha ) == sha ); + assert( fd_blake3_append( sha, msg, size ) == sha ); + assert( fd_blake3_fini( sha, hash2 ) == hash2 ); + assert( !memcmp( hash1, hash2, 32UL ) ); + + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/bmtree/fuzz_bmtree.c b/src/ballet/bmtree/fuzz_bmtree.c index 952b19d34a..ccf9090c3b 100644 --- a/src/ballet/bmtree/fuzz_bmtree.c +++ b/src/ballet/bmtree/fuzz_bmtree.c @@ -7,6 +7,7 @@ #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_bmtree.h" #define MAX_LEAF_CNT (256UL) @@ -107,6 +108,7 @@ fuzz_bmtree( fd_bmtree_node_t const * leafs, int res = fd_bmtree_get_proof( tree, inc_proof, i ); if ( res == -1 ) { + FD_FUZZ_MUST_BE_COVERED; return 0; } @@ -119,6 +121,7 @@ fuzz_bmtree( fd_bmtree_node_t const * leafs, assert( fd_memeq( root_1, proof_root_2, hash_sz ) ); if( FD_LIKELY( leaf_cnt>1UL ) ) { + FD_FUZZ_MUST_BE_COVERED; inc_proof[ 1 ]++; /* Corrupt the proof */ assert( proof_root_1 == fd_bmtree_from_proof( leaf, i, proof_root_1, inc_proof, depth-1UL, hash_sz, prefix_sz ) ); @@ -174,5 +177,8 @@ LLVMFuzzerTestOneInput( uchar const * data, return result; } - return fuzz_bmtree( leafs, leaf_cnt, 20UL, FD_BMTREE_LONG_PREFIX_SZ ); + result = fuzz_bmtree( leafs, leaf_cnt, 20UL, FD_BMTREE_LONG_PREFIX_SZ ); + + FD_FUZZ_MUST_BE_COVERED; + return result; } diff --git a/src/ballet/ed25519/Local.mk b/src/ballet/ed25519/Local.mk index b541add211..e1fa1617ba 100644 --- a/src/ballet/ed25519/Local.mk +++ b/src/ballet/ed25519/Local.mk @@ -4,7 +4,6 @@ $(call make-unit-test,test_ed25519,test_ed25519,fd_ballet fd_util) $(call make-unit-test,test_ed25519_signature_malleability,test_ed25519_signature_malleability,fd_ballet fd_util) $(call make-unit-test,test_x25519,test_x25519,fd_ballet fd_util) $(call fuzz-test,fuzz_ed25519_verify,fuzz_ed25519_verify,fd_ballet fd_util) -$(call fuzz-test,fuzz_ed25519_sign,fuzz_ed25519_sign,fd_ballet fd_util) $(call fuzz-test,fuzz_ed25519_sigverify,fuzz_ed25519_sigverify,fd_ballet fd_util) $(call run-unit-test,test_ed25519) diff --git a/src/ballet/ed25519/fuzz_ed25519_sign.c b/src/ballet/ed25519/fuzz_ed25519_sign.c deleted file mode 100644 index 5106c12ac0..0000000000 --- a/src/ballet/ed25519/fuzz_ed25519_sign.c +++ /dev/null @@ -1,49 +0,0 @@ -#if !FD_HAS_HOSTED -#error "This target requires FD_HAS_HOSTED" -#endif - -#include -#include - -#include "../../util/fd_util.h" -#include "fd_ed25519.h" - -int -LLVMFuzzerInitialize( int * argc, - char *** argv ) { - /* Set up shell without signal handlers */ - putenv( "FD_LOG_BACKTRACE=0" ); - fd_boot( argc, argv ); - atexit( fd_halt ); - return 0; -} - -struct signature_test { - uchar prv[ 32 ]; - uchar msg[ ]; -}; -typedef struct signature_test signature_test_t; - -int -LLVMFuzzerTestOneInput( uchar const * data, - ulong size ) { - if( FD_UNLIKELY( size<32UL ) ) return -1; - - signature_test_t * const test = ( signature_test_t * const ) data; - ulong sz = size-32UL; - - fd_sha512_t _sha[1]; - fd_sha512_t *sha = fd_sha512_join( fd_sha512_new( _sha ) ); - - uchar pub[ 32 ]; - fd_ed25519_public_from_private( pub, test->prv, sha ); - - uchar sig[64]; - void * result = fd_ed25519_sign( sig, test->msg, sz, pub, test->prv, sha ); - int cmp = memcmp( ( char * ) sig, ( char * ) result, 64UL ); - if( FD_UNLIKELY( cmp!=0 ) ) { - __builtin_trap(); - } - - return 0; -} diff --git a/src/ballet/ed25519/fuzz_ed25519_sigverify.c b/src/ballet/ed25519/fuzz_ed25519_sigverify.c index 6f852993ef..27430d5863 100644 --- a/src/ballet/ed25519/fuzz_ed25519_sigverify.c +++ b/src/ballet/ed25519/fuzz_ed25519_sigverify.c @@ -2,10 +2,12 @@ #error "This target requires FD_HAS_HOSTED" #endif +#include #include #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_ed25519.h" int @@ -41,14 +43,11 @@ LLVMFuzzerTestOneInput( uchar const * data, uchar sig[ 64 ]; void * sig_result = fd_ed25519_sign( sig, test->msg, sz, pub, test->prv, sha ); int cmp = memcmp( ( char * ) sig, ( char * ) sig_result, 64UL ); - if( FD_UNLIKELY( cmp!=0 ) ) { - __builtin_trap(); - } + assert( cmp == 0 ); int verify_result = fd_ed25519_verify( test->msg, sz, sig, pub, sha ); - if( verify_result != FD_ED25519_SUCCESS ) { - __builtin_trap(); - } + assert( verify_result == FD_ED25519_SUCCESS ); + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/ed25519/fuzz_ed25519_verify.c b/src/ballet/ed25519/fuzz_ed25519_verify.c index b9fe28264f..855665a466 100644 --- a/src/ballet/ed25519/fuzz_ed25519_verify.c +++ b/src/ballet/ed25519/fuzz_ed25519_verify.c @@ -2,10 +2,12 @@ #error "This target requires FD_HAS_HOSTED" #endif +#include #include #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_ed25519.h" int @@ -25,6 +27,8 @@ struct verification_test { }; typedef struct verification_test verification_test_t; +/* This fuzzer tries to verify random data */ + int LLVMFuzzerTestOneInput( uchar const * data, ulong size ) { @@ -37,10 +41,8 @@ LLVMFuzzerTestOneInput( uchar const * data, fd_sha512_t *sha = fd_sha512_join( fd_sha512_new( _sha ) ); int result = fd_ed25519_verify( test->msg, sz, test->sig, test->pub, sha ); - if( FD_UNLIKELY( result == FD_ED25519_SUCCESS ) ) { - // was able to verify fuzz input - __builtin_trap(); - } - + assert( result != FD_ED25519_SUCCESS ); + + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/hex/fuzz_hex.c b/src/ballet/hex/fuzz_hex.c index cbf1bc6922..acdfa655c7 100644 --- a/src/ballet/hex/fuzz_hex.c +++ b/src/ballet/hex/fuzz_hex.c @@ -2,10 +2,12 @@ #error "This target requires FD_HAS_HOSTED" #endif +#include #include #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_hex.h" int @@ -47,9 +49,8 @@ LLVMFuzzerTestOneInput( uchar const * data, uchar decoded[ MAX_DECODED_SZ ]; ulong decoded_sz = fd_hex_decode( decoded, encoded, size/2UL ); - if( FD_UNLIKELY( decoded_sz!=( check_hex_encoding( encoded, size )/2UL ) ) ) { - __builtin_trap(); - } + assert( decoded_sz == ( check_hex_encoding( encoded, size )/2UL ) ); + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/hmac/fuzz_hmac.c b/src/ballet/hmac/fuzz_hmac.c index 261dcf536a..770f8c02de 100644 --- a/src/ballet/hmac/fuzz_hmac.c +++ b/src/ballet/hmac/fuzz_hmac.c @@ -2,10 +2,12 @@ #error "This target requires FD_HAS_HOSTED" #endif +#include #include #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_hmac.h" #include "../sha256/fd_sha256.h" #include "../sha512/fd_sha512.h" @@ -45,35 +47,18 @@ LLVMFuzzerTestOneInput( uchar const * data, uchar hash1[ 64 ] __attribute__((aligned(64))); uchar hash2[ 64 ] __attribute__((aligned(64))); - if( FD_UNLIKELY( fd_hmac_sha256( msg, msg_size, key, key_size, hash1 )!=hash1 ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( fd_hmac_sha256( msg, msg_size, key, key_size, hash2 )!=hash2 ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( memcmp( hash1, hash2, FD_SHA256_HASH_SZ ) ) ) { - __builtin_trap(); - } + assert( fd_hmac_sha256( msg, msg_size, key, key_size, hash1 ) == hash1 ); + assert( fd_hmac_sha256( msg, msg_size, key, key_size, hash2 ) == hash2 ); + assert( !memcmp( hash1, hash2, FD_SHA256_HASH_SZ ) ); - if( FD_UNLIKELY( fd_hmac_sha384( msg, msg_size, key, key_size, hash1 )!=hash1 ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( fd_hmac_sha384( msg, msg_size, key, key_size, hash2 )!=hash2 ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( memcmp( hash1, hash2, FD_SHA384_HASH_SZ ) ) ) { - __builtin_trap(); - } + assert( fd_hmac_sha384( msg, msg_size, key, key_size, hash1 ) == hash1 ); + assert( fd_hmac_sha384( msg, msg_size, key, key_size, hash2 ) == hash2 ); + assert( !memcmp( hash1, hash2, FD_SHA384_HASH_SZ ) ); - if( FD_UNLIKELY( fd_hmac_sha512( msg, msg_size, key, key_size, hash1 )!=hash1 ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( fd_hmac_sha512( msg, msg_size, key, key_size, hash2 )!=hash2 ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( memcmp( hash1, hash2, FD_SHA512_HASH_SZ ) ) ) { - __builtin_trap(); - } + assert( fd_hmac_sha512( msg, msg_size, key, key_size, hash1 ) == hash1 ); + assert( fd_hmac_sha512( msg, msg_size, key, key_size, hash2 ) == hash2 ); + assert( !memcmp( hash1, hash2, FD_SHA512_HASH_SZ ) ); + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/http/fuzz_picohttpparser.c b/src/ballet/http/fuzz_picohttpparser.c index ca2619d95d..0ded35d301 100644 --- a/src/ballet/http/fuzz_picohttpparser.c +++ b/src/ballet/http/fuzz_picohttpparser.c @@ -8,6 +8,7 @@ #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "picohttpparser.h" int @@ -48,6 +49,7 @@ LLVMFuzzerTestOneInput( uchar const * data, headers, &header_cnt, 0UL ); if( res==0 ) { + FD_FUZZ_MUST_BE_COVERED; assert( method_len < size ); assert( path_len < size ); assert( header_cnt <= HEADER_CAP ); @@ -55,6 +57,8 @@ LLVMFuzzerTestOneInput( uchar const * data, assert( headers[i].name_len < size ); assert( headers[i].value_len < size ); } + } else { + FD_FUZZ_MUST_BE_COVERED; } } while(0); @@ -71,6 +75,7 @@ LLVMFuzzerTestOneInput( uchar const * data, int ok = 0; for( ulong cursor=0UL; cursor #include #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_keccak256.h" int @@ -21,30 +23,20 @@ LLVMFuzzerInitialize( int * argc, int LLVMFuzzerTestOneInput( uchar const * data, ulong size ) { - // hash single message + /* hash single message */ char const * msg = ( char const * ) data; uchar hash1[ 32 ] __attribute__((aligned(32))); uchar hash2[ 32 ] __attribute__((aligned(32))); fd_keccak256_t sha[1]; - if( FD_UNLIKELY( fd_keccak256_init( sha )!=sha ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( fd_keccak256_append( sha, msg, size )!=sha ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( fd_keccak256_fini( sha, hash1 )!=hash1 ) ) { - __builtin_trap(); - } - - if( FD_UNLIKELY( fd_keccak256_hash( data, size, hash2 )!=hash2 ) ) { - __builtin_trap(); - } - - if( FD_UNLIKELY( memcmp( hash1, hash2, 32UL ) ) ) { - __builtin_trap(); - } + assert( fd_keccak256_init( sha ) == sha ); + assert( fd_keccak256_append( sha, msg, size ) == sha ); + assert( fd_keccak256_fini( sha, hash1 ) == hash1 ); + assert( fd_keccak256_hash( data, size, hash2 ) == hash2 ); + assert( !memcmp( hash1, hash2, 32UL ) ); + + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/murmur3/fuzz_murmur3.c b/src/ballet/murmur3/fuzz_murmur3.c index 6f8b415eb5..c69420139e 100644 --- a/src/ballet/murmur3/fuzz_murmur3.c +++ b/src/ballet/murmur3/fuzz_murmur3.c @@ -2,10 +2,12 @@ #error "This target requires FD_HAS_HOSTED" #endif +#include #include #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_murmur3.h" int @@ -27,9 +29,8 @@ LLVMFuzzerTestOneInput( uchar const * data, uint hash1 = fd_murmur3_32( msg, size, 0 ); uint hash2 = fd_murmur3_32( msg, size, 0 ); - if( FD_UNLIKELY( hash1!=hash2 ) ) { - __builtin_trap(); - } + assert( hash1 == hash2 ); + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/reedsol/fuzz_reedsol.c b/src/ballet/reedsol/fuzz_reedsol.c index 8bdc57f1e3..3892e530ad 100644 --- a/src/ballet/reedsol/fuzz_reedsol.c +++ b/src/ballet/reedsol/fuzz_reedsol.c @@ -6,6 +6,7 @@ #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_reedsol.h" int @@ -130,5 +131,6 @@ LLVMFuzzerTestOneInput( uchar const * data, else p[ corrupt_idx-d_cnt ][ byte_idx ] ^= (uchar)1; fd_rng_delete( fd_rng_leave( rng ) ); + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/sbpf/fuzz_sbpf_loader.c b/src/ballet/sbpf/fuzz_sbpf_loader.c index f276a87d81..82295c4478 100644 --- a/src/ballet/sbpf/fuzz_sbpf_loader.c +++ b/src/ballet/sbpf/fuzz_sbpf_loader.c @@ -66,5 +66,6 @@ LLVMFuzzerTestOneInput( uchar const * data, free( rodata ); free( fd_sbpf_syscalls_delete( syscalls ) ); free( fd_sbpf_program_delete( prog ) ); + return 0; } diff --git a/src/ballet/sha256/fuzz_sha256.c b/src/ballet/sha256/fuzz_sha256.c index 07bb1fbede..2dc4458fc3 100644 --- a/src/ballet/sha256/fuzz_sha256.c +++ b/src/ballet/sha256/fuzz_sha256.c @@ -7,6 +7,7 @@ #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_sha256.h" #define BATCH_CNT 32UL /* must be at least 1UL */ @@ -69,11 +70,13 @@ LLVMFuzzerTestOneInput( uchar const * fuzz_data, // batch hashing if( fuzz_sz>=BATCH_CNT ) { + FD_FUZZ_MUST_BE_COVERED; assert( fd_sha256_batch_init( batch_sha ) == batch_sha ); ulong entry_sz = fuzz_sz/BATCH_CNT; for( ulong batch_idx=0UL; batch_idx #include #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_sha512.h" int @@ -28,23 +30,14 @@ LLVMFuzzerTestOneInput( uchar const * data, uchar hash2[ 48 ] __attribute__((aligned(64))); fd_sha384_t sha[1]; - if( FD_UNLIKELY( fd_sha384_init( sha )!=sha ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( fd_sha384_append( sha, msg, size )!=sha ) ) { - __builtin_trap(); - } - if( FD_UNLIKELY( fd_sha384_fini( sha, hash1 )!=hash1 ) ) { - __builtin_trap(); - } - - if( FD_UNLIKELY( fd_sha384_hash( data, size, hash2 )!=hash2 ) ) { - __builtin_trap(); - } - - if( FD_UNLIKELY( memcmp( hash1, hash2, 48UL ) ) ) { - __builtin_trap(); - } + assert( fd_sha384_init( sha ) == sha ); + assert( fd_sha384_append( sha, msg, size ) == sha ); + assert( fd_sha384_fini( sha, hash1 ) == hash1 ); + assert( fd_sha384_hash( data, size, hash2 ) == hash2 ); + + assert( !memcmp( hash1, hash2, 48UL ) ); + + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/sha512/fuzz_sha512.c b/src/ballet/sha512/fuzz_sha512.c index 53042607b6..7248bec9aa 100644 --- a/src/ballet/sha512/fuzz_sha512.c +++ b/src/ballet/sha512/fuzz_sha512.c @@ -7,6 +7,7 @@ #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_sha512.h" #define BATCH_CNT 32UL /* must be at least 1UL */ @@ -69,11 +70,13 @@ LLVMFuzzerTestOneInput( uchar const * fuzz_data, // batch hashing if( fuzz_sz>=BATCH_CNT ) { + FD_FUZZ_MUST_BE_COVERED; assert( fd_sha512_batch_init( batch_sha ) == batch_sha ); ulong entry_sz = fuzz_sz/BATCH_CNT; for( ulong batch_idx=0UL; batch_idx #include #include +#include "../../util/sanitize/fd_fuzz.h" #include "../../util/fd_util.h" #include "fd_shred.h" @@ -26,21 +28,29 @@ LLVMFuzzerTestOneInput( uchar const * data, if( shred==NULL ) return 0; if( fd_shred_merkle_cnt( shred->variant ) ) { - if( (ulong)(fd_shred_merkle_nodes( shred )+fd_shred_merkle_cnt( shred->variant )) > (ulong)(data+size) ) __builtin_trap(); + assert( (ulong)(fd_shred_merkle_nodes( shred )+fd_shred_merkle_cnt( shred->variant )) <= (ulong)(data+size) ); } switch( fd_shred_type( shred->variant ) ) { case FD_SHRED_TYPE_LEGACY_CODE: + FD_FUZZ_MUST_BE_COVERED; + __attribute__((fallthrough)); case FD_SHRED_TYPE_MERKLE_CODE: - if( fd_shred_code_payload( shred )+fd_shred_payload_sz( shred ) > data+size ) __builtin_trap(); + FD_FUZZ_MUST_BE_COVERED; + assert( fd_shred_code_payload( shred )+fd_shred_payload_sz( shred ) <= data+size ); break; case FD_SHRED_TYPE_LEGACY_DATA: + FD_FUZZ_MUST_BE_COVERED; + __attribute__((fallthrough)); case FD_SHRED_TYPE_MERKLE_DATA: - if( fd_shred_data_payload( shred )+fd_shred_payload_sz( shred ) > data+size ) __builtin_trap(); + FD_FUZZ_MUST_BE_COVERED; + assert( fd_shred_data_payload( shred )+fd_shred_payload_sz( shred ) <= data+size ); break; default: - __builtin_trap(); + /* unknown variant */ + __builtin_unreachable(); break; } + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/siphash13/fuzz_siphash13.c b/src/ballet/siphash13/fuzz_siphash13.c index 8037bc2d8b..33b8fe643d 100644 --- a/src/ballet/siphash13/fuzz_siphash13.c +++ b/src/ballet/siphash13/fuzz_siphash13.c @@ -7,6 +7,7 @@ #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_siphash13.h" fd_siphash13_t * sip; @@ -76,5 +77,6 @@ LLVMFuzzerTestOneInput( uchar const * fuzz_data, ulong hash_fast = fd_siphash13_fini( sip_fast ); assert( hash == hash_fast ); + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/ballet/txn/fuzz_txn_parse.c b/src/ballet/txn/fuzz_txn_parse.c index f43e403971..5671d1bf6c 100644 --- a/src/ballet/txn/fuzz_txn_parse.c +++ b/src/ballet/txn/fuzz_txn_parse.c @@ -6,6 +6,7 @@ #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_txn.h" int @@ -30,9 +31,11 @@ LLVMFuzzerTestOneInput( uchar const * data, __asm__ volatile( "" : "+m,r"(sz) : : "memory" ); /* prevent optimization */ if( FD_LIKELY( sz>0UL ) ) { + FD_FUZZ_MUST_BE_COVERED; fd_txn_t * txn = (fd_txn_t *)txn_buf; FD_TEST( fd_txn_footprint( txn->instr_cnt, txn->addr_table_lookup_cnt )<=FD_TXN_MAX_SZ ); } + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/tango/quic/templ/fuzz_quic_parse_transport_params.c b/src/tango/quic/templ/fuzz_quic_parse_transport_params.c index 554d6c7380..d934688fb3 100644 --- a/src/tango/quic/templ/fuzz_quic_parse_transport_params.c +++ b/src/tango/quic/templ/fuzz_quic_parse_transport_params.c @@ -2,6 +2,7 @@ #include #include "../../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "../fd_quic_common.h" #include "../fd_quic_config.h" #include "fd_quic_transport_params.h" @@ -22,5 +23,6 @@ LLVMFuzzerTestOneInput( uchar const * data, ulong size ) { fd_quic_transport_params_t out; fd_quic_decode_transport_params( &out, data, size ); + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/tango/quic/tests/fuzz_quic.c b/src/tango/quic/tests/fuzz_quic.c index aa8ed58f5d..3bb60d6fa8 100644 --- a/src/tango/quic/tests/fuzz_quic.c +++ b/src/tango/quic/tests/fuzz_quic.c @@ -6,6 +6,8 @@ #include #include +#include "../../../util/sanitize/fd_fuzz.h" + #include "../fd_quic.h" #include "../fd_quic_private.h" #include "../fd_quic_proto.h" @@ -213,14 +215,17 @@ int LLVMFuzzerTestOneInput(uchar const *data, ulong size) { fd_quic_init(server_quic); while (s > 2) { + FD_FUZZ_MUST_BE_COVERED; ushort payload_sz = (ushort)( ptr[0] + ( ptr[1] << 8u ) ); ptr += 2; s -= 2; if (payload_sz <= s) { send_packet(ptr, payload_sz); + FD_FUZZ_MUST_BE_COVERED; ptr += payload_sz; s -= payload_sz; } else { + FD_FUZZ_MUST_BE_COVERED; fd_quic_fini(server_quic); return 0; } @@ -228,5 +233,6 @@ int LLVMFuzzerTestOneInput(uchar const *data, ulong size) { fd_quic_fini(server_quic); + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/util/archive/fuzz_tar.c b/src/util/archive/fuzz_tar.c index b5d3536e94..748e135543 100644 --- a/src/util/archive/fuzz_tar.c +++ b/src/util/archive/fuzz_tar.c @@ -6,6 +6,7 @@ #include #include "../../util/fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "fd_tar.h" int @@ -75,6 +76,7 @@ LLVMFuzzerTestOneInput( uchar const * data, /* Read byte by byte */ int err2 = 0; for( ulong i=0UL; i #include "../fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "./fd_pcap.h" int @@ -26,7 +27,9 @@ int LLVMFuzzerTestOneInput( uchar const * data, ulong size ) { - if( FD_UNLIKELY( size==0UL ) ) return 0; +/* > Before glibc 2.22, if size is specified as zero, fmemopen() fails with the error EINVAL. + - https://man7.org/linux/man-pages/man3/fmemopen.3.html */ +if( FD_UNLIKELY( size==0UL ) ) return 0; FILE * file = fmemopen( (void *)data, size, "rb" ); FD_TEST( file ); @@ -34,6 +37,7 @@ LLVMFuzzerTestOneInput( uchar const * data, /* Open "pcap". */ fd_pcap_iter_t * pcap = fd_pcap_iter_new( file ); if ( FD_LIKELY( pcap ) ) { + FD_FUZZ_MUST_BE_COVERED; /* Loop over all packets */ uchar buf[128]; long pkt_ts; @@ -44,5 +48,7 @@ LLVMFuzzerTestOneInput( uchar const * data, } FD_TEST( 0==fclose( file ) ); + + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/util/net/fuzz_pcapng.c b/src/util/net/fuzz_pcapng.c index dda2160876..6e9baa2423 100644 --- a/src/util/net/fuzz_pcapng.c +++ b/src/util/net/fuzz_pcapng.c @@ -7,6 +7,7 @@ #include #include "../fd_util.h" +#include "../../util/sanitize/fd_fuzz.h" #include "./fd_pcapng_private.h" int @@ -51,6 +52,7 @@ LLVMFuzzerTestOneInput( uchar const * data, }; for(;;) { + FD_FUZZ_MUST_BE_COVERED; fd_pcapng_frame_t const * frame = fd_pcapng_iter_next( &iter ); if( !frame ) break; @@ -68,6 +70,8 @@ LLVMFuzzerTestOneInput( uchar const * data, } FD_TEST( 0==fclose( file ) ); + + FD_FUZZ_MUST_BE_COVERED; return 0; } diff --git a/src/util/sanitize/fd_fuzz.h b/src/util/sanitize/fd_fuzz.h index b07e8a1dde..9f44c766c9 100644 --- a/src/util/sanitize/fd_fuzz.h +++ b/src/util/sanitize/fd_fuzz.h @@ -1,11 +1,10 @@ #ifndef HEADER_fd_src_util_fuzz_fd_fuzz_h #define HEADER_fd_src_util_fuzz_fd_fuzz_h -#if FD_HAS_FUZZ +#if FD_HAS_COVERAGE && FD_HAS_FUZZ #define FD_FUZZ_MUST_BE_COVERED ((void) 0) #else #define FD_FUZZ_MUST_BE_COVERED #endif - #endif