diff --git a/.github/workflows/fuzz-testrun.yml b/.github/workflows/fuzz-testrun.yml new file mode 100644 index 0000000000000..be38f15288e50 --- /dev/null +++ b/.github/workflows/fuzz-testrun.yml @@ -0,0 +1,25 @@ +--- +name: Error Injection Testrun + +on: + pull_request: + push: + schedule: + - cron: '0 10 * * *' + +permissions: + contents: read + +jobs: + fuzzing_testrun: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: checkout fuzz/corpora submodule + run: git submodule update --init --depth 1 fuzz/corpora + - name: config + run: ./config --strict-warnings enable-asan enable-ubsan enable-rc5 enable-md2 enable-ec_nistp_64_gcc_128 -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -DERROR_INJECT -DERROR_CALLSTACK && perl configdata.pm --dump + - name: make + run: make -s -j4 + - name: fuzzing... + run: ./util/shlib_wrap.sh ./apps/openssl version -a && cd fuzz && (sh -c 'sleep 3600; touch stop.signal; sleep 60; test -f stop.signal && killall -6 -r ".*-test";' &) && ASAN_OPTIONS=handle_abort=true ./testrun.sh && test ! -f *-test.out diff --git a/fuzz/asn1.c b/fuzz/asn1.c index ee602a08a3d91..1785c7fe9d9b8 100644 --- a/fuzz/asn1.c +++ b/fuzz/asn1.c @@ -286,6 +286,9 @@ int FuzzerInitialize(int *argc, char ***argv) { FuzzerSetRand(); pctx = ASN1_PCTX_new(); + if (pctx == NULL) + return 0; + ASN1_PCTX_set_flags(pctx, ASN1_PCTX_FLAGS_SHOW_ABSENT | ASN1_PCTX_FLAGS_SHOW_SEQUENCE | ASN1_PCTX_FLAGS_SHOW_SSOF | ASN1_PCTX_FLAGS_SHOW_TYPE | ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME); diff --git a/fuzz/bignum.c b/fuzz/bignum.c index d7c3716aacb43..72466b27c3499 100644 --- a/fuzz/bignum.c +++ b/fuzz/bignum.c @@ -45,6 +45,9 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) b4 = BN_new(); b5 = BN_new(); ctx = BN_CTX_new(); + if (b1 == NULL || b2 == NULL || b3 == NULL + || b4 == NULL || b5 == NULL || ctx == NULL) + goto err; /* Divide the input into three parts, using the values of the first two * bytes to choose lengths, which generate b1, b2 and b3. Use three bits @@ -62,10 +65,13 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) s3 = buf[0] & 4; ++buf; } - OPENSSL_assert(BN_bin2bn(buf, l1, b1) == b1); + if (BN_bin2bn(buf, l1, b1) != b1) + goto done; BN_set_negative(b1, s1); - OPENSSL_assert(BN_bin2bn(buf + l1, l2, b2) == b2); - OPENSSL_assert(BN_bin2bn(buf + l1 + l2, l3, b3) == b3); + if (BN_bin2bn(buf + l1, l2, b2) != b2) + goto done; + if (BN_bin2bn(buf + l1 + l2, l3, b3) != b3) + goto done; BN_set_negative(b3, s3); /* mod 0 is undefined */ @@ -74,8 +80,10 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) goto done; } - OPENSSL_assert(BN_mod_exp(b4, b1, b2, b3, ctx)); - OPENSSL_assert(BN_mod_exp_simple(b5, b1, b2, b3, ctx)); + if (!BN_mod_exp(b4, b1, b2, b3, ctx)) + goto done; + if (!BN_mod_exp_simple(b5, b1, b2, b3, ctx)) + goto done; success = BN_cmp(b4, b5) == 0; if (!success) { @@ -90,9 +98,14 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) BN_print_fp(stdout, b5); putchar('\n'); } + OPENSSL_assert(success); done: +#ifndef ERROR_INJECT OPENSSL_assert(success); +#endif + + err: BN_free(b1); BN_free(b2); BN_free(b3); diff --git a/fuzz/bndiv.c b/fuzz/bndiv.c index d9467b5e8b412..2cd9db320a487 100644 --- a/fuzz/bndiv.c +++ b/fuzz/bndiv.c @@ -21,22 +21,8 @@ /* 256 kB */ #define MAX_LEN (256 * 1000) -static BN_CTX *ctx; -static BIGNUM *b1; -static BIGNUM *b2; -static BIGNUM *b3; -static BIGNUM *b4; -static BIGNUM *b5; - int FuzzerInitialize(int *argc, char ***argv) { - b1 = BN_new(); - b2 = BN_new(); - b3 = BN_new(); - b4 = BN_new(); - b5 = BN_new(); - ctx = BN_CTX_new(); - OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); ERR_clear_error(); @@ -49,6 +35,22 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) size_t l1 = 0, l2 = 0; /* s1 and s2 will be the signs for b1 and b2. */ int s1 = 0, s2 = 0; + BN_CTX *ctx; + BIGNUM *b1; + BIGNUM *b2; + BIGNUM *b3; + BIGNUM *b4; + BIGNUM *b5; + + b1 = BN_new(); + b2 = BN_new(); + b3 = BN_new(); + b4 = BN_new(); + b5 = BN_new(); + ctx = BN_CTX_new(); + if (b1 == NULL || b2 == NULL || b3 == NULL + || b4 == NULL || b5 == NULL || ctx == NULL) + goto err; /* limit the size of the input to avoid timeout */ if (len > MAX_LEN) @@ -69,9 +71,11 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) ++buf; l2 = len - l1; } - OPENSSL_assert(BN_bin2bn(buf, l1, b1) == b1); + if (BN_bin2bn(buf, l1, b1) != b1) + goto done; BN_set_negative(b1, s1); - OPENSSL_assert(BN_bin2bn(buf + l1, l2, b2) == b2); + if (BN_bin2bn(buf + l1, l2, b2) != b2) + goto done; BN_set_negative(b2, s2); /* divide by 0 is an error */ @@ -80,7 +84,12 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) goto done; } - OPENSSL_assert(BN_div(b3, b4, b1, b2, ctx)); + if (!BN_div(b3, b4, b1, b2, ctx)) + goto done; + if (!BN_mul(b5, b3, b2, ctx)) + goto done; + if (!BN_add(b5, b5, b4)) + goto done; if (BN_is_zero(b1)) success = BN_is_zero(b3) && BN_is_zero(b4); else if (BN_is_negative(b1)) @@ -89,8 +98,6 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) else success = (BN_is_negative(b3) == BN_is_negative(b2) || BN_is_zero(b3)) && (!BN_is_negative(b4) || BN_is_zero(b4)); - OPENSSL_assert(BN_mul(b5, b3, b2, ctx)); - OPENSSL_assert(BN_add(b5, b5, b4)); success = success && BN_cmp(b5, b1) == 0; if (!success) { @@ -112,20 +119,25 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) BN_cmp(b5, b1)); puts("----\n"); } + OPENSSL_assert(success); done: +#ifndef ERROR_INJECT OPENSSL_assert(success); - ERR_clear_error(); +#endif - return 0; -} - -void FuzzerCleanup(void) -{ + err: BN_free(b1); BN_free(b2); BN_free(b3); BN_free(b4); BN_free(b5); BN_CTX_free(ctx); + ERR_clear_error(); + + return 0; +} + +void FuzzerCleanup(void) +{ } diff --git a/fuzz/client.c b/fuzz/client.c index 1754add50967d..b1a1d091a2dd9 100644 --- a/fuzz/client.c +++ b/fuzz/client.c @@ -72,7 +72,8 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) if (client == NULL) goto end; OPENSSL_assert(SSL_set_min_proto_version(client, 0) == 1); - OPENSSL_assert(SSL_set_cipher_list(client, "ALL:eNULL:@SECLEVEL=0") == 1); + if (SSL_set_cipher_list(client, "ALL:eNULL:@SECLEVEL=0") != 1) + goto end; SSL_set_tlsext_host_name(client, "localhost"); in = BIO_new(BIO_s_mem()); if (in == NULL) @@ -84,7 +85,8 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) } SSL_set_bio(client, in, out); SSL_set_connect_state(client); - OPENSSL_assert((size_t)BIO_write(in, buf, len) == len); + if ((size_t)BIO_write(in, buf, len) != len) + goto end; if (SSL_do_handshake(client) == 1) { /* Keep reading application data until error or EOF. */ uint8_t tmp[1024]; diff --git a/fuzz/cmp.c b/fuzz/cmp.c index 490c4211f8e29..0bdff1cc4a5d4 100644 --- a/fuzz/cmp.c +++ b/fuzz/cmp.c @@ -164,7 +164,10 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) return 0; in = BIO_new(BIO_s_mem()); - OPENSSL_assert((size_t)BIO_write(in, buf, len) == len); + if ((size_t)BIO_write(in, buf, len) != len) { + BIO_free(in); + return 0; + } msg = d2i_OSSL_CMP_MSG_bio(in, NULL); if (msg != NULL) { BIO *out = BIO_new(BIO_s_null()); diff --git a/fuzz/cms.c b/fuzz/cms.c index d464429a54079..16f359b3a84f4 100644 --- a/fuzz/cms.c +++ b/fuzz/cms.c @@ -34,7 +34,10 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) return 0; in = BIO_new(BIO_s_mem()); - OPENSSL_assert((size_t)BIO_write(in, buf, len) == len); + if ((size_t)BIO_write(in, buf, len) != len) { + BIO_free(in); + return 0; + } cms = d2i_CMS_bio(in, NULL); if (cms != NULL) { BIO *out = BIO_new(BIO_s_null()); diff --git a/fuzz/conf.c b/fuzz/conf.c index 72e4b358fd86f..3ae06dae2dca2 100644 --- a/fuzz/conf.c +++ b/fuzz/conf.c @@ -34,7 +34,11 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) conf = NCONF_new(NULL); in = BIO_new(BIO_s_mem()); - OPENSSL_assert((size_t)BIO_write(in, buf, len) == len); + if ((size_t)BIO_write(in, buf, len) != len) { + BIO_free(in); + NCONF_free(conf); + return 0; + } NCONF_load_bio(conf, in, &eline); NCONF_free(conf); BIO_free(in); diff --git a/fuzz/decoder.c b/fuzz/decoder.c index 1a6558dbb3a26..38f558b667ec7 100644 --- a/fuzz/decoder.c +++ b/fuzz/decoder.c @@ -45,12 +45,12 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) EVP_PKEY_CTX *ctx = NULL; BIO *bio; - bio = BIO_new(BIO_s_null()); dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, NULL, NULL, NULL, 0, NULL, NULL); - if (dctx == NULL) { + if (dctx == NULL) return 0; - } + + bio = BIO_new(BIO_s_null()); if (OSSL_DECODER_from_data(dctx, &buf, &len)) { EVP_PKEY *pkey2; @@ -59,16 +59,22 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) EVP_PKEY_print_params(bio, pkey, 1, pctx); pkey2 = EVP_PKEY_dup(pkey); +#ifndef ERROR_INJECT OPENSSL_assert(pkey2 != NULL); +#endif EVP_PKEY_eq(pkey, pkey2); EVP_PKEY_free(pkey2); ctx = EVP_PKEY_CTX_new(pkey, NULL); - EVP_PKEY_param_check(ctx); - EVP_PKEY_public_check(ctx); - EVP_PKEY_private_check(ctx); - EVP_PKEY_pairwise_check(ctx); +#ifndef ERROR_INJECT OPENSSL_assert(ctx != NULL); +#endif + if (ctx != NULL) { + EVP_PKEY_param_check(ctx); + EVP_PKEY_public_check(ctx); + EVP_PKEY_private_check(ctx); + EVP_PKEY_pairwise_check(ctx); + } EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); } diff --git a/fuzz/fuzz_rand.c b/fuzz/fuzz_rand.c index af9df7b22d31a..978ef01e02965 100644 --- a/fuzz/fuzz_rand.c +++ b/fuzz/fuzz_rand.c @@ -159,7 +159,11 @@ void FuzzerSetRand(void) if (!OSSL_PROVIDER_add_builtin(NULL, "fuzz-rand", fuzz_rand_provider_init) || !RAND_set_DRBG_type(NULL, "fuzz", NULL, NULL, NULL) || (r_prov = OSSL_PROVIDER_try_load(NULL, "fuzz-rand", 1)) == NULL) +#ifdef ERROR_INJECT + exit(0); +#else exit(1); +#endif } void FuzzerClearRand(void) diff --git a/fuzz/pem.c b/fuzz/pem.c index 4b2cf701e711a..0626b1aa0bfca 100644 --- a/fuzz/pem.c +++ b/fuzz/pem.c @@ -31,12 +31,15 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) return 0; in = BIO_new(BIO_s_mem()); - OPENSSL_assert((size_t)BIO_write(in, buf + 1, len - 1) == len - 1); + if ((size_t)BIO_write(in, buf + 1, len - 1) != len - 1) { + BIO_free(in); + return 0; + } if (PEM_read_bio_ex(in, &name, &header, &data, &outlen, buf[0]) == 1) { - /* Try to read all the data we get to see if allocated properly. */ + /* Try to read all the data we get to see if allocated properly. */ BIO_write(in, name, strlen(name)); - BIO_write(in, header, strlen(header)); - BIO_write(in, data, outlen); + BIO_write(in, header, strlen(header)); + BIO_write(in, data, outlen); } if (buf[0] & PEM_FLAG_SECURE) { OPENSSL_secure_free(name); diff --git a/fuzz/server.c b/fuzz/server.c index e481e5621ce39..656711eff9ceb 100644 --- a/fuzz/server.c +++ b/fuzz/server.c @@ -540,18 +540,32 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) /* This only fuzzes the initial flow from the client so far. */ ctx = SSL_CTX_new(SSLv23_method()); + if (ctx == NULL) + return 0; ret = SSL_CTX_set_min_proto_version(ctx, 0); OPENSSL_assert(ret == 1); ret = SSL_CTX_set_cipher_list(ctx, "ALL:eNULL:@SECLEVEL=0"); - OPENSSL_assert(ret == 1); + if (ret != 1) { + SSL_CTX_free(ctx); + return 0; + } #ifndef OPENSSL_NO_DEPRECATED_3_0 /* RSA */ bufp = kRSAPrivateKeyDER; privkey = d2i_RSAPrivateKey(NULL, &bufp, sizeof(kRSAPrivateKeyDER)); + if (privkey == NULL) { + SSL_CTX_free(ctx); + return 0; + } OPENSSL_assert(privkey != NULL); pkey = EVP_PKEY_new(); + if (pkey == NULL) { + RSA_free(privkey); + SSL_CTX_free(ctx); + return 0; + } EVP_PKEY_assign_RSA(pkey, privkey); ret = SSL_CTX_use_PrivateKey(ctx, pkey); OPENSSL_assert(ret == 1); @@ -560,61 +574,124 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) bufp = kCertificateDER; cert = d2i_X509(NULL, &bufp, sizeof(kCertificateDER)); + if (cert == NULL) { + SSL_CTX_free(ctx); + return 0; + } OPENSSL_assert(cert != NULL); ret = SSL_CTX_use_certificate(ctx, cert); - OPENSSL_assert(ret == 1); X509_free(cert); + if (ret != 1) { + SSL_CTX_free(ctx); + return 0; + } #ifndef OPENSSL_NO_EC # ifndef OPENSSL_NO_DEPRECATED_3_0 /* ECDSA */ bio_buf = BIO_new(BIO_s_mem()); - OPENSSL_assert((size_t)BIO_write(bio_buf, ECDSAPrivateKeyPEM, sizeof(ECDSAPrivateKeyPEM)) == sizeof(ECDSAPrivateKeyPEM)); + if ((size_t)BIO_write(bio_buf, ECDSAPrivateKeyPEM, sizeof(ECDSAPrivateKeyPEM)) != sizeof(ECDSAPrivateKeyPEM)) { + BIO_free(bio_buf); + SSL_CTX_free(ctx); + return 0; + } ecdsakey = PEM_read_bio_ECPrivateKey(bio_buf, NULL, NULL, NULL); ERR_print_errors_fp(stderr); + if (ecdsakey == NULL) { + BIO_free(bio_buf); + SSL_CTX_free(ctx); + return 0; + } OPENSSL_assert(ecdsakey != NULL); BIO_free(bio_buf); pkey = EVP_PKEY_new(); + if (pkey == NULL) { + EC_KEY_free(ecdsakey); + SSL_CTX_free(ctx); + return 0; + } EVP_PKEY_assign_EC_KEY(pkey, ecdsakey); ret = SSL_CTX_use_PrivateKey(ctx, pkey); OPENSSL_assert(ret == 1); EVP_PKEY_free(pkey); # endif bio_buf = BIO_new(BIO_s_mem()); - OPENSSL_assert((size_t)BIO_write(bio_buf, ECDSACertPEM, sizeof(ECDSACertPEM)) == sizeof(ECDSACertPEM)); + if ((size_t)BIO_write(bio_buf, ECDSACertPEM, sizeof(ECDSACertPEM)) != sizeof(ECDSACertPEM)) { + BIO_free(bio_buf); + SSL_CTX_free(ctx); + return 0; + } cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); + if (cert == NULL) { + BIO_free(bio_buf); + SSL_CTX_free(ctx); + return 0; + } OPENSSL_assert(cert != NULL); BIO_free(bio_buf); ret = SSL_CTX_use_certificate(ctx, cert); - OPENSSL_assert(ret == 1); X509_free(cert); + if (ret != 1) { + SSL_CTX_free(ctx); + return 0; + } #endif #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) /* DSA */ bio_buf = BIO_new(BIO_s_mem()); - OPENSSL_assert((size_t)BIO_write(bio_buf, DSAPrivateKeyPEM, sizeof(DSAPrivateKeyPEM)) == sizeof(DSAPrivateKeyPEM)); + if ((size_t)BIO_write(bio_buf, DSAPrivateKeyPEM, sizeof(DSAPrivateKeyPEM)) != sizeof(DSAPrivateKeyPEM)) { + BIO_free(bio_buf); + SSL_CTX_free(ctx); + return 0; + } dsakey = PEM_read_bio_DSAPrivateKey(bio_buf, NULL, NULL, NULL); ERR_print_errors_fp(stderr); + if (dsakey == NULL) { + BIO_free(bio_buf); + SSL_CTX_free(ctx); + return 0; + } OPENSSL_assert(dsakey != NULL); BIO_free(bio_buf); pkey = EVP_PKEY_new(); + if (pkey == NULL) { + DSA_free(dsakey); + SSL_CTX_free(ctx); + return 0; + } EVP_PKEY_assign_DSA(pkey, dsakey); ret = SSL_CTX_use_PrivateKey(ctx, pkey); OPENSSL_assert(ret == 1); EVP_PKEY_free(pkey); bio_buf = BIO_new(BIO_s_mem()); - OPENSSL_assert((size_t)BIO_write(bio_buf, DSACertPEM, sizeof(DSACertPEM)) == sizeof(DSACertPEM)); + if ((size_t)BIO_write(bio_buf, DSACertPEM, sizeof(DSACertPEM)) != sizeof(DSACertPEM)) { + BIO_free(bio_buf); + SSL_CTX_free(ctx); + return 0; + } cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); + if (cert == NULL) { + BIO_free(bio_buf); + SSL_CTX_free(ctx); + return 0; + } OPENSSL_assert(cert != NULL); BIO_free(bio_buf); ret = SSL_CTX_use_certificate(ctx, cert); - OPENSSL_assert(ret == 1); X509_free(cert); + if (ret != 1) { + SSL_CTX_free(ctx); + return 0; + } #endif server = SSL_new(ctx); + if (server == NULL) { + SSL_CTX_free(ctx); + return 0; + } in = BIO_new(BIO_s_mem()); out = BIO_new(BIO_s_mem()); SSL_set_bio(server, in, out); @@ -623,7 +700,11 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) opt = (uint8_t)buf[len-1]; len--; - OPENSSL_assert((size_t)BIO_write(in, buf, len) == len); + if ((size_t)BIO_write(in, buf, len) != len) { + SSL_free(server); + SSL_CTX_free(ctx); + return 0; + } if ((opt & 0x01) != 0) { diff --git a/fuzz/test-corpus.c b/fuzz/test-corpus.c index aaeec778603f7..878971d090a40 100644 --- a/fuzz/test-corpus.c +++ b/fuzz/test-corpus.c @@ -22,6 +22,131 @@ #include "fuzzer.h" #include "internal/o_dir.h" +#ifdef ERROR_INJECT +# ifdef __linux__ +# include +# endif +# ifdef __SANITIZE_ADDRESS__ +# include +# endif + +static uint64_t my_seed = 88172645463325252LL; + +static void my_srand(uint32_t seed) +{ + uint64_t y = seed; + y ^= (~y) << 32; + my_seed = y; +} + +static uint32_t my_rand(void) +{ + /* + * Implement the 64 bit xorshift as suggested by George Marsaglia in: + * https://doi.org/10.18637/jss.v008.i14 + */ + uint64_t y = my_seed; + y ^= y << 13; + y ^= y >> 7; + y ^= y << 17; + my_seed = y; + return y; +} + +static void my_init(void) +{ + static int init = 0; + if (!init) { + uint32_t seed; + char *env = getenv("ERROR_INJECT"); + + if (env != NULL && *env) { + seed = atoi(env); + } else { +# ifdef __linux__ + struct timeval tv; + + gettimeofday(&tv, NULL); + seed = (uint32_t)(tv.tv_sec ^ tv.tv_usec); +# else + seed = (uint32_t)time(NULL); +# endif + } + my_srand(seed); + init = 1; + if (env && !*env) { +# ifdef __SANITIZE_ADDRESS__ + char msg[40]; + + sprintf(msg, "ERROR_INJECT=%u", seed); + __sanitizer_report_error_summary(msg); +# else + fprintf(stderr, "ERROR_INJECT=%u\n", seed); + fflush(stderr); +# endif + } + } +} + +# ifdef ERROR_CALLSTACK +# ifdef __SANITIZE_ADDRESS__ +# define MY_NULL (__sanitizer_print_stack_trace(),NULL) +# else +void break_here(void); +void break_here(void) +{ +} +# define MY_NULL (break_here(),NULL) +# endif +# else +# define MY_NULL NULL +# endif + +static void* my_malloc(size_t s +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + , const char *file + , int line +#endif + ) +{ +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + (void)file; + (void)line; +#endif + my_init(); + return my_rand() % 10000 ? malloc(s) : MY_NULL; +} + +static void* my_realloc(void *p, size_t s +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + , const char *file + , int line +#endif + ) +{ +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + (void)file; + (void)line; +#endif + my_init(); + return my_rand() % 100 ? realloc(p, s) : MY_NULL; +} + +static void my_free(void *p +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + , const char *file + , int line +#endif + ) +{ +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + (void)file; + (void)line; +#endif + free(p); +} +#endif /* ERROR_INJECT */ + #if defined(_WIN32) && defined(_MAX_PATH) && !defined(PATH_MAX) # define PATH_MAX _MAX_PATH #endif @@ -52,6 +177,11 @@ static void testfile(const char *pathname) if (buf != NULL) { s = fread(buf, 1, st.st_size, f); OPENSSL_assert(s == (size_t)st.st_size); +#ifdef ERROR_INJECT + if (s > 0) + while (my_rand() % 3 <= 1) + buf[my_rand() % s] = (unsigned char)my_rand(); +#endif FuzzerTestOneInput(buf, s); free(buf); } @@ -61,6 +191,9 @@ static void testfile(const char *pathname) int main(int argc, char **argv) { int n; +#ifdef ERROR_INJECT + CRYPTO_set_mem_functions(my_malloc, my_realloc, my_free); +#endif FuzzerInitialize(&argc, &argv); for (n = 1; n < argc; ++n) { diff --git a/fuzz/testrun.sh b/fuzz/testrun.sh new file mode 100755 index 0000000000000..c1bf84f5f50cf --- /dev/null +++ b/fuzz/testrun.sh @@ -0,0 +1,29 @@ +#! /bin/bash +while true +do + for X in `ls -I "*.*" ./corpora` + do + echo `date`: running $X + for Y in `ls ./corpora/$X` + do + UBSAN_OPTIONS=${UBSAN_OPTIONS:-print_stacktrace=1} \ + ERROR_INJECT=${ERROR_INJECT:-} \ + ../util/shlib_wrap.sh ./$X-test ./corpora/$X/$Y &> $X-$Y-$$-test.out + if [ $? != 0 ] + then + echo `date`: error detected + echo `grep ERROR_INJECT= $X-$Y-$$-test.out` ../util/shlib_wrap.sh ./$X-test ./corpora/$X/$Y + echo log file: $X-$Y-$$-test.out + cat $X-$Y-$$-test.out + exit + fi + rm $X-$Y-$$-test.out + if [ -f stop.signal ] + then + rm stop.signal + echo `date`: stopped + exit + fi + done + done +done