Skip to content

Commit

Permalink
Make the fuzzers more reproducible
Browse files Browse the repository at this point in the history
We want to be in the same global state each time we come in
FuzzerTestOneInput(). There are various reasons why we might not be that
include:
- Initialization that happens on first use. This is mostly the
  RUN_ONCE() things, or loading of error strings.
- Results that get cached. For instance a stack that is sorted, RSA
  blinding that has been set up, ...

So I try to trigger as much as possible in FuzzerInitialize(), and for
things I didn't find out how to trigger this it needs to happen in
FuzzerTestOneInput().

Reviewed-by: Rich Salz <[email protected]>
GH: openssl#2023
  • Loading branch information
kroeckx committed Dec 2, 2016
1 parent 0282aeb commit d69d8f9
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 27 deletions.
5 changes: 5 additions & 0 deletions fuzz/asn1parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,24 @@
#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include "fuzzer.h"

static BIO *bio_out;

int FuzzerInitialize(int *argc, char ***argv)
{
bio_out = BIO_new_file("/dev/null", "w");
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
ERR_get_state();
CRYPTO_free_ex_index(0, -1);
return 1;
}

int FuzzerTestOneInput(const uint8_t *buf, size_t len)
{
(void)ASN1_parse_dump(bio_out, buf, len, 0, 0);
ERR_clear_error();
return 0;
}

Expand Down
5 changes: 5 additions & 0 deletions fuzz/bndiv.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include <stdio.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include "fuzzer.h"

static BN_CTX *ctx;
Expand All @@ -33,6 +34,9 @@ int FuzzerInitialize(int *argc, char ***argv)
b5 = BN_new();
ctx = BN_CTX_new();

OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
ERR_get_state();

return 1;
}

Expand Down Expand Up @@ -104,6 +108,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)

done:
OPENSSL_assert(success);
ERR_clear_error();

return 0;
}
Expand Down
5 changes: 5 additions & 0 deletions fuzz/cms.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@

#include <openssl/bio.h>
#include <openssl/cms.h>
#include <openssl/err.h>
#include "fuzzer.h"

int FuzzerInitialize(int *argc, char ***argv)
{
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
ERR_get_state();
CRYPTO_free_ex_index(0, -1);
return 1;
}

Expand All @@ -41,6 +45,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
}

BIO_free(in);
ERR_clear_error();

return 0;
}
Expand Down
4 changes: 4 additions & 0 deletions fuzz/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
*/

#include <openssl/conf.h>
#include <openssl/err.h>
#include "fuzzer.h"

int FuzzerInitialize(int *argc, char ***argv)
{
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
ERR_get_state();
return 1;
}

Expand All @@ -35,6 +38,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
NCONF_load_bio(conf, in, &eline);
NCONF_free(conf);
BIO_free(in);
ERR_clear_error();

return 0;
}
Expand Down
6 changes: 6 additions & 0 deletions fuzz/crl.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@

#include <openssl/x509.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include "fuzzer.h"

int FuzzerInitialize(int *argc, char ***argv)
{
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
ERR_get_state();
CRYPTO_free_ex_index(0, -1);
return 1;
}

Expand All @@ -33,6 +37,8 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)

X509_CRL_free(crl);
}
ERR_clear_error();

return 0;
}

Expand Down
5 changes: 5 additions & 0 deletions fuzz/ct.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@

#include <stdio.h>
#include <openssl/ct.h>
#include <openssl/err.h>
#include "fuzzer.h"

int FuzzerInitialize(int *argc, char ***argv)
{
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
CRYPTO_free_ex_index(0, -1);
ERR_get_state();
return 1;
}

Expand All @@ -38,6 +42,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)

SCT_LIST_free(scts);
}
ERR_clear_error();
return 0;
}

Expand Down
73 changes: 46 additions & 27 deletions fuzz/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include "fuzzer.h"

static const uint8_t kCertificateDER[] = {
Expand Down Expand Up @@ -189,34 +190,29 @@ static const uint8_t kRSAPrivateKeyDER[] = {
0x98, 0x46, 0x89, 0x82, 0x40,
};

static SSL_CTX *ctx;

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
extern int rand_predictable;
#endif
#define ENTROPY_NEEDED 32

/* unused, to avoid warning. */
static int idx;

int FuzzerInitialize(int *argc, char ***argv)
{
const uint8_t *bufp = kRSAPrivateKeyDER;
RSA *privkey;
EVP_PKEY *pkey;
int ret;
X509 *cert;
STACK_OF(SSL_COMP) *comp_methods;

OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ASYNC, NULL);
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
ERR_get_state();
CRYPTO_free_ex_index(0, -1);
idx = SSL_get_ex_data_X509_STORE_CTX_idx();
RAND_add("", 1, ENTROPY_NEEDED);
RAND_status();
RSA_get_default_method();
comp_methods = SSL_COMP_get_compression_methods();
OPENSSL_sk_sort((OPENSSL_STACK *)comp_methods);

ctx = SSL_CTX_new(SSLv23_method());
privkey = d2i_RSAPrivateKey(NULL, &bufp, sizeof(kRSAPrivateKeyDER));
OPENSSL_assert(privkey != NULL);
pkey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pkey, privkey);
ret = SSL_CTX_use_PrivateKey(ctx, pkey);
OPENSSL_assert(ret == 1);
EVP_PKEY_free(pkey);
bufp = kCertificateDER;
cert = d2i_X509(NULL, &bufp, sizeof(kCertificateDER));
OPENSSL_assert(cert != NULL);
ret = SSL_CTX_use_certificate(ctx, cert);
OPENSSL_assert(ret == 1);
X509_free(cert);

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
rand_predictable = 1;
Expand All @@ -230,16 +226,37 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
SSL *server;
BIO *in;
BIO *out;
if (!len) {
SSL_CTX *ctx;
int ret;
RSA *privkey;
const uint8_t *bufp = kRSAPrivateKeyDER;
EVP_PKEY *pkey;
X509 *cert;

if (len == 0)
return 0;
}
/* TODO: make this work for OpenSSL. There's a PREDICT define that may do
* the job.

/*
* TODO: use the ossltest engine (optionally?) to disable crypto checks.
* RAND_reset_for_fuzzing();
*/

/* This only fuzzes the initial flow from the client so far. */
ctx = SSL_CTX_new(SSLv23_method());
privkey = d2i_RSAPrivateKey(NULL, &bufp, sizeof(kRSAPrivateKeyDER));
OPENSSL_assert(privkey != NULL);
pkey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pkey, privkey);
ret = SSL_CTX_use_PrivateKey(ctx, pkey);
OPENSSL_assert(ret == 1);
EVP_PKEY_free(pkey);

bufp = kCertificateDER;
cert = d2i_X509(NULL, &bufp, sizeof(kCertificateDER));
OPENSSL_assert(cert != NULL);
ret = SSL_CTX_use_certificate(ctx, cert);
OPENSSL_assert(ret == 1);
X509_free(cert);

server = SSL_new(ctx);
in = BIO_new(BIO_s_mem());
out = BIO_new(BIO_s_mem());
Expand All @@ -256,10 +273,12 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
}
}
SSL_free(server);
ERR_clear_error();
SSL_CTX_free(ctx);

return 0;
}

void FuzzerCleanup(void)
{
SSL_CTX_free(ctx);
}
5 changes: 5 additions & 0 deletions fuzz/x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@

#include <openssl/x509.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include "fuzzer.h"

int FuzzerInitialize(int *argc, char ***argv)
{
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
ERR_get_state();
CRYPTO_free_ex_index(0, -1);
return 1;
}

Expand All @@ -34,6 +38,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)

X509_free(x509);
}
ERR_clear_error();
return 0;
}

Expand Down

0 comments on commit d69d8f9

Please sign in to comment.