From: Jakub Zelenka Date: Wed, 22 Apr 2026 13:33:23 +0000 (+0200) Subject: Fix fuzz test to handle memory failures X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=c263ea553c1d19f12d0040ecd184e4bf4e054af3;p=thirdparty%2Fopenssl.git Fix fuzz test to handle memory failures It also fixes related memory leaks and removes extensive asserts that should not be present in fuzzy tests. Reviewed-by: Nikola Pajkovsky Reviewed-by: Tomas Mraz MergeDate: Wed Jul 15 16:01:42 2026 (Merged from https://github.com/openssl/openssl/pull/30944) --- diff --git a/fuzz/acert.c b/fuzz/acert.c index 14c2f657eec..3af3c3e87a4 100644 --- a/fuzz/acert.c +++ b/fuzz/acert.c @@ -26,13 +26,16 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) { const unsigned char *p = buf; unsigned char *der = NULL; + X509_ACERT *acert; - X509_ACERT *acert = d2i_X509_ACERT(NULL, &p, (long)len); + acert = d2i_X509_ACERT(NULL, &p, (long)len); if (acert != NULL) { BIO *bio = BIO_new(BIO_s_null()); - X509_ACERT_print(bio, acert); - BIO_free(bio); + if (bio != NULL) { + X509_ACERT_print(bio, acert); + BIO_free(bio); + } i2d_X509_ACERT(acert, &der); OPENSSL_free(der); diff --git a/fuzz/asn1.c b/fuzz/asn1.c index 934e1447e94..12ba8a13d47 100644 --- a/fuzz/asn1.c +++ b/fuzz/asn1.c @@ -277,9 +277,6 @@ static ASN1_PCTX *pctx; TYPE *type = D2I(NULL, &p, (long)len); \ \ if (type != NULL) { \ - BIO *bio = BIO_new(BIO_s_null()); \ - \ - BIO_free(bio); \ I2D(type, &der); \ OPENSSL_free(der); \ TYPE##_free(type); \ @@ -290,6 +287,8 @@ 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); ASN1_PCTX_set_str_flags(pctx, ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_SHOW_TYPE | ASN1_STRFLGS_DUMP_ALL); diff --git a/fuzz/bignum.c b/fuzz/bignum.c index b9dcb49ebef..eec776e7b3e 100644 --- a/fuzz/bignum.c +++ b/fuzz/bignum.c @@ -28,7 +28,6 @@ int FuzzerInitialize(int *argc, char ***argv) int FuzzerTestOneInput(const uint8_t *buf, size_t len) { - int success = 0; size_t l1 = 0, l2 = 0, l3 = 0; int s1 = 0, s3 = 0; BN_CTX *ctx; @@ -45,6 +44,10 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) b5 = BN_new(); ctx = BN_CTX_new(); + if (b1 == NULL || b2 == NULL || b3 == NULL || b4 == NULL || b5 == NULL + || ctx == NULL) + goto done; + /* 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 * of the third byte to choose signs for the three numbers. @@ -62,23 +65,25 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) s3 = buf[0] & 4; ++buf; } - OPENSSL_assert(BN_bin2bn(buf, (int)l1, b1) == b1); + if (BN_bin2bn(buf, (int)l1, b1) != b1) + goto done; BN_set_negative(b1, s1); - OPENSSL_assert(BN_bin2bn(buf + l1, (int)l2, b2) == b2); - OPENSSL_assert(BN_bin2bn(buf + l1 + l2, (int)l3, b3) == b3); + if (BN_bin2bn(buf + l1, (int)l2, b2) != b2) + goto done; + if (BN_bin2bn(buf + l1 + l2, (int)l3, b3) != b3) + goto done; BN_set_negative(b3, s3); /* mod 0 is undefined */ - if (BN_is_zero(b3)) { - success = 1; + if (BN_is_zero(b3)) 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) { + if (BN_cmp(b4, b5) != 0) { BN_print_fp(stdout, b1); putchar('\n'); BN_print_fp(stdout, b2); @@ -92,7 +97,6 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) } done: - OPENSSL_assert(success); BN_free(b1); BN_free(b2); BN_free(b3); diff --git a/fuzz/bndiv.c b/fuzz/bndiv.c index a52f7b598b4..c3a2d2f305f 100644 --- a/fuzz/bndiv.c +++ b/fuzz/bndiv.c @@ -37,6 +37,19 @@ int FuzzerInitialize(int *argc, char ***argv) b5 = BN_new(); ctx = BN_CTX_new(); + if (b1 == NULL || b2 == NULL || b3 == NULL || b4 == NULL || b5 == NULL + || ctx == NULL) { + BN_free(b1); + BN_free(b2); + BN_free(b3); + BN_free(b4); + BN_free(b5); + BN_CTX_free(ctx); + b1 = b2 = b3 = b4 = b5 = NULL; + ctx = NULL; + return 0; + } + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); ERR_clear_error(); @@ -69,18 +82,19 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) ++buf; l2 = len - l1; } - OPENSSL_assert(BN_bin2bn(buf, (int)l1, b1) == b1); + if (BN_bin2bn(buf, (int)l1, b1) != b1) + goto done; BN_set_negative(b1, s1); - OPENSSL_assert(BN_bin2bn(buf + l1, (int)l2, b2) == b2); + if (BN_bin2bn(buf + l1, (int)l2, b2) != b2) + goto done; BN_set_negative(b2, s2); /* divide by 0 is an error */ - if (BN_is_zero(b2)) { - success = 1; + if (BN_is_zero(b2)) goto done; - } - OPENSSL_assert(BN_div(b3, b4, b1, b2, ctx)); + if (!BN_div(b3, b4, b1, b2, ctx)) + goto done; if (BN_is_zero(b1)) success = BN_is_zero(b3) && BN_is_zero(b4); else if (BN_is_negative(b1)) @@ -89,8 +103,10 @@ 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)); + if (!BN_mul(b5, b3, b2, ctx)) + goto done; + if (!BN_add(b5, b5, b4)) + goto done; success = success && BN_cmp(b5, b1) == 0; if (!success) { @@ -114,7 +130,6 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) } done: - OPENSSL_assert(success); ERR_clear_error(); return 0; diff --git a/fuzz/client.c b/fuzz/client.c index 86cec0cd435..64d30dd09eb 100644 --- a/fuzz/client.c +++ b/fuzz/client.c @@ -76,8 +76,10 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) client = SSL_new(ctx); 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_min_proto_version(client, 0) != 1) + goto end; + 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) @@ -89,7 +91,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, (int)len) == len); + if ((size_t)BIO_write(in, buf, (int)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 c86d390f8bc..ae4dcc033d8 100644 --- a/fuzz/cmp.c +++ b/fuzz/cmp.c @@ -176,8 +176,13 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) return 0; in = BIO_new(BIO_s_mem()); + if (in == NULL) { + ERR_clear_error(); + return 0; + } if ((size_t)BIO_write(in, buf, (int)len) != len) { BIO_free(in); + ERR_clear_error(); return 0; } diff --git a/fuzz/cms.c b/fuzz/cms.c index 0cd8ea95512..d45bf1b63c0 100644 --- a/fuzz/cms.c +++ b/fuzz/cms.c @@ -34,13 +34,23 @@ 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, (int)len) == len); + if (in == NULL) { + ERR_clear_error(); + return 0; + } + if ((size_t)BIO_write(in, buf, (int)len) != len) { + BIO_free(in); + ERR_clear_error(); + return 0; + } cms = d2i_CMS_bio(in, NULL); if (cms != NULL) { BIO *out = BIO_new(BIO_s_null()); - i2d_CMS_bio(out, cms); - BIO_free(out); + if (out != NULL) { + i2d_CMS_bio(out, cms); + BIO_free(out); + } CMS_ContentInfo_free(cms); } diff --git a/fuzz/conf.c b/fuzz/conf.c index 9c5353868bd..116759a0a1f 100644 --- a/fuzz/conf.c +++ b/fuzz/conf.c @@ -33,9 +33,15 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) return 0; conf = NCONF_new(NULL); + if (conf == NULL) + return 0; in = BIO_new(BIO_s_mem()); - OPENSSL_assert((size_t)BIO_write(in, buf, (int)len) == len); + if (in == NULL) + goto end; + if ((size_t)BIO_write(in, buf, (int)len) != len) + goto end; NCONF_load_bio(conf, in, &eline); +end: NCONF_free(conf); BIO_free(in); ERR_clear_error(); diff --git a/fuzz/crl.c b/fuzz/crl.c index c22f5d55e22..f704321ac5f 100644 --- a/fuzz/crl.c +++ b/fuzz/crl.c @@ -29,8 +29,11 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) X509_CRL *crl = d2i_X509_CRL(NULL, &p, (long)len); if (crl != NULL) { BIO *bio = BIO_new(BIO_s_null()); - X509_CRL_print(bio, crl); - BIO_free(bio); + + if (bio != NULL) { + X509_CRL_print(bio, crl); + BIO_free(bio); + } i2d_X509_CRL(crl, &der); OPENSSL_free(der); diff --git a/fuzz/ct.c b/fuzz/ct.c index e46574d8ebc..74fbf66c042 100644 --- a/fuzz/ct.c +++ b/fuzz/ct.c @@ -32,8 +32,11 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) STACK_OF(SCT) *scts = d2i_SCT_LIST(NULL, pp, (long)len); if (scts != NULL) { BIO *bio = BIO_new(BIO_s_null()); - SCT_LIST_print(scts, bio, 4, "\n", NULL); - BIO_free(bio); + + if (bio != NULL) { + SCT_LIST_print(scts, bio, 4, "\n", NULL); + BIO_free(bio); + } if (i2d_SCT_LIST(scts, &der)) { /* Silence unused result warning */ diff --git a/fuzz/decoder.c b/fuzz/decoder.c index 3a9a48ad218..227c24fd71f 100644 --- a/fuzz/decoder.c +++ b/fuzz/decoder.c @@ -25,6 +25,8 @@ int FuzzerInitialize(int *argc, char ***argv) NULL); 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); ASN1_PCTX_set_str_flags(pctx, ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_SHOW_TYPE | ASN1_STRFLGS_DUMP_ALL); @@ -41,9 +43,15 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) BIO *bio; bio = BIO_new(BIO_s_null()); + if (bio == NULL) { + ERR_clear_error(); + return 0; + } dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, NULL, NULL, NULL, 0, NULL, NULL); if (dctx == NULL) { + BIO_free(bio); + ERR_clear_error(); return 0; } if (OSSL_DECODER_from_data(dctx, &buf, &len)) { @@ -54,27 +62,29 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) EVP_PKEY_print_params(bio, pkey, 1, pctx); pkey2 = EVP_PKEY_dup(pkey); - OPENSSL_assert(pkey2 != NULL); - EVP_PKEY_eq(pkey, pkey2); - EVP_PKEY_free(pkey2); + if (pkey2 != NULL) { + EVP_PKEY_eq(pkey, pkey2); + EVP_PKEY_free(pkey2); + } ctx = EVP_PKEY_CTX_new(pkey, NULL); - /* - * Param check will take too long time on large DH parameters. - * Skip it. - */ - if ((!EVP_PKEY_is_a(pkey, "DH") && !EVP_PKEY_is_a(pkey, "DHX")) - || EVP_PKEY_get_bits(pkey) <= 2048) - EVP_PKEY_param_check(ctx); + if (ctx != NULL) { + /* + * Param check will take too long time on large DH parameters. + * Skip it. + */ + if ((!EVP_PKEY_is_a(pkey, "DH") && !EVP_PKEY_is_a(pkey, "DHX")) + || EVP_PKEY_get_bits(pkey) <= 2048) + EVP_PKEY_param_check(ctx); - EVP_PKEY_public_check(ctx); - /* Private and pairwise checks are unbounded, skip for large keys. */ - if (EVP_PKEY_get_bits(pkey) <= 4096) { - EVP_PKEY_private_check(ctx); - EVP_PKEY_pairwise_check(ctx); + EVP_PKEY_public_check(ctx); + /* Private and pairwise checks are unbounded, skip for large keys. */ + if (EVP_PKEY_get_bits(pkey) <= 4096) { + EVP_PKEY_private_check(ctx); + EVP_PKEY_pairwise_check(ctx); + } + EVP_PKEY_CTX_free(ctx); } - OPENSSL_assert(ctx != NULL); - EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); } OSSL_DECODER_CTX_free(dctx); diff --git a/fuzz/dtlsclient.c b/fuzz/dtlsclient.c index f07bc6ed676..2dc5ed709c0 100644 --- a/fuzz/dtlsclient.c +++ b/fuzz/dtlsclient.c @@ -76,8 +76,10 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) client = SSL_new(ctx); 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_min_proto_version(client, 0) != 1) + goto end; + 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) @@ -89,7 +91,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, (int)len) == len); + if ((size_t)BIO_write(in, buf, (int)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/dtlsserver.c b/fuzz/dtlsserver.c index 15c6c8bb571..84ded9a4dfc 100644 --- a/fuzz/dtlsserver.c +++ b/fuzz/dtlsserver.c @@ -218,7 +218,6 @@ static const uint8_t RSACertificatePEM[] = { 0x2d, 0x0a }; -#ifndef OPENSSL_NO_DEPRECATED_3_0 /* -----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC1mQfTLWrNFfUs @@ -464,10 +463,8 @@ static const uint8_t RSAPrivateKeyPEM[] = { 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a }; -#endif #ifndef OPENSSL_NO_EC -#ifndef OPENSSL_NO_DEPRECATED_3_0 /* -----BEGIN EC PRIVATE KEY----- MHcCAQEEIJLyl7hJjpQL/RhP1x2zS79xdiPJQB683gWeqcqHPeZkoAoGCCqGSM49 @@ -496,7 +493,6 @@ static const char ECDSAPrivateKeyPEM[] = { 0x4e, 0x44, 0x20, 0x45, 0x43, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a }; -#endif /* -----BEGIN CERTIFICATE----- @@ -559,7 +555,7 @@ static const char ECDSACertPEM[] = { }; #endif -#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) +#ifndef OPENSSL_NO_DSA /* -----BEGIN DSA PRIVATE KEY----- MIIBuwIBAAKBgQDdkFKzNABLOha7Eqj7004+p5fhtR6bxpujToMmSZTYi8igVVXP @@ -779,121 +775,109 @@ time_t time(time_t *t) TIME_IMPL(t) return 1; } +static int use_pem_privkey(SSL_CTX *ctx, const void *pem, size_t pem_len) +{ + BIO *bio_buf; + EVP_PKEY *pkey; + int rv = 0; + + bio_buf = BIO_new(BIO_s_mem()); + if (bio_buf == NULL) + return 0; + if ((size_t)BIO_write(bio_buf, pem, (int)pem_len) != pem_len) { + BIO_free(bio_buf); + return 0; + } + pkey = PEM_read_bio_PrivateKey(bio_buf, NULL, NULL, NULL); + BIO_free(bio_buf); + if (pkey == NULL) + return 0; + if (SSL_CTX_use_PrivateKey(ctx, pkey) == 1) + rv = 1; + EVP_PKEY_free(pkey); + return rv; +} + +static int use_pem_cert(SSL_CTX *ctx, const void *pem, size_t pem_len) +{ + BIO *bio_buf; + X509 *cert; + int rv = 0; + + bio_buf = BIO_new(BIO_s_mem()); + if (bio_buf == NULL) + return 0; + if ((size_t)BIO_write(bio_buf, pem, (int)pem_len) != pem_len) { + BIO_free(bio_buf); + return 0; + } + cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); + BIO_free(bio_buf); + if (cert == NULL) + return 0; + if (SSL_CTX_use_certificate(ctx, cert) == 1) + rv = 1; + X509_free(cert); + return rv; +} + int FuzzerTestOneInput(const uint8_t *buf, size_t len) { - SSL *server; + SSL *server = NULL; BIO *in; BIO *out; - BIO *bio_buf; SSL_CTX *ctx; - int ret; -#ifndef OPENSSL_NO_DEPRECATED_3_0 - RSA *privkey; -#endif -#if !defined(OPENSSL_NO_DEPRECATED_3_0) - EVP_PKEY *pkey; -#endif - X509 *cert; -#ifndef OPENSSL_NO_DEPRECATED_3_0 -#ifndef OPENSSL_NO_EC - EC_KEY *ecdsakey = NULL; -#endif -#endif -#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) - DSA *dsakey = NULL; -#endif if (len < 2 || len > INT_MAX) return 0; - /* This only fuzzes the initial flow from the client so far. */ ctx = SSL_CTX_new(DTLS_server_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 (SSL_CTX_set_min_proto_version(ctx, 0) != 1) + goto end; + if (SSL_CTX_set_cipher_list(ctx, "ALL:eNULL:@SECLEVEL=0") != 1) + goto end; -#ifndef OPENSSL_NO_DEPRECATED_3_0 /* RSA */ - bio_buf = BIO_new(BIO_s_mem()); - OPENSSL_assert((size_t)BIO_write(bio_buf, RSAPrivateKeyPEM, sizeof(RSAPrivateKeyPEM)) == sizeof(RSAPrivateKeyPEM)); - privkey = PEM_read_bio_RSAPrivateKey(bio_buf, NULL, NULL, NULL); - ERR_print_errors_fp(stderr); - OPENSSL_assert(privkey != NULL); - BIO_free(bio_buf); - 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); -#endif - - bio_buf = BIO_new(BIO_s_mem()); - OPENSSL_assert((size_t)BIO_write(bio_buf, RSACertificatePEM, sizeof(RSACertificatePEM)) == sizeof(RSACertificatePEM)); - cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); - BIO_free(bio_buf); - OPENSSL_assert(cert != NULL); - ret = SSL_CTX_use_certificate(ctx, cert); - OPENSSL_assert(ret == 1); - X509_free(cert); + if (!use_pem_privkey(ctx, RSAPrivateKeyPEM, sizeof(RSAPrivateKeyPEM))) + goto end; + if (!use_pem_cert(ctx, RSACertificatePEM, sizeof(RSACertificatePEM))) + goto end; #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)); - ecdsakey = PEM_read_bio_ECPrivateKey(bio_buf, NULL, NULL, NULL); - ERR_print_errors_fp(stderr); - OPENSSL_assert(ecdsakey != NULL); - BIO_free(bio_buf); - pkey = EVP_PKEY_new(); - 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)); - cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); - OPENSSL_assert(cert != NULL); - BIO_free(bio_buf); - ret = SSL_CTX_use_certificate(ctx, cert); - OPENSSL_assert(ret == 1); - X509_free(cert); + if (!use_pem_privkey(ctx, ECDSAPrivateKeyPEM, sizeof(ECDSAPrivateKeyPEM))) + goto end; + if (!use_pem_cert(ctx, ECDSACertPEM, sizeof(ECDSACertPEM))) + goto end; #endif -#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) +#ifndef OPENSSL_NO_DSA /* DSA */ - bio_buf = BIO_new(BIO_s_mem()); - OPENSSL_assert((size_t)BIO_write(bio_buf, DSAPrivateKeyPEM, sizeof(DSAPrivateKeyPEM)) == sizeof(DSAPrivateKeyPEM)); - dsakey = PEM_read_bio_DSAPrivateKey(bio_buf, NULL, NULL, NULL); - ERR_print_errors_fp(stderr); - OPENSSL_assert(dsakey != NULL); - BIO_free(bio_buf); - pkey = EVP_PKEY_new(); - 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)); - cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); - OPENSSL_assert(cert != NULL); - BIO_free(bio_buf); - ret = SSL_CTX_use_certificate(ctx, cert); - OPENSSL_assert(ret == 1); - X509_free(cert); + if (!use_pem_privkey(ctx, DSAPrivateKeyPEM, sizeof(DSAPrivateKeyPEM))) + goto end; + if (!use_pem_cert(ctx, DSACertPEM, sizeof(DSACertPEM))) + goto end; #endif server = SSL_new(ctx); + if (server == NULL) + goto end; in = BIO_new(BIO_s_mem()); + if (in == NULL) + goto end; out = BIO_new(BIO_s_mem()); + if (out == NULL) { + BIO_free(in); + goto end; + } SSL_set_bio(server, in, out); SSL_set_accept_state(server); - OPENSSL_assert((size_t)BIO_write(in, buf, (int)len) == len); + if ((size_t)BIO_write(in, buf, (int)len) != len) + goto end; if (SSL_do_handshake(server) == 1) { /* Keep reading application data until error or EOF. */ @@ -904,6 +888,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) } } } +end: SSL_free(server); ERR_clear_error(); SSL_CTX_free(ctx); diff --git a/fuzz/hashtable.c b/fuzz/hashtable.c index 9e9519b8652..9eb81c0a9ef 100644 --- a/fuzz/hashtable.c +++ b/fuzz/hashtable.c @@ -162,22 +162,11 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) /* set the proper key value */ HT_SET_KEY_FIELD(&key, fuzzkey, keyval); + memcpy(&valptr->value, &buf[3], sizeof(uint64_t)); + /* lock the table */ ossl_ht_write_lock(fuzzer_table); - /* - * If the value to insert is already allocated - * then we expect a conflict in the insert - * i.e. we predict a return code of 0 instead - * of 1. On replacement, we expect it to succeed - * always - */ - if (valptr->flags & FZ_FLAG_ALLOCATED) { - if (!IS_REPLACE(op_flags)) - rc_prediction = 0; - } - - memcpy(&valptr->value, &buf[3], sizeof(uint64_t)); /* * do the insert/replace */ @@ -188,30 +177,18 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) rc = ossl_ht_fz_FUZZER_VALUE_insert(fuzzer_table, TO_HT_KEY(&key), valptr, NULL); - if (rc == -1) - /* failed to grow the hash table due to too many collisions */ - break; - - /* - * mark the entry as being allocated - */ - valptr->flags |= FZ_FLAG_ALLOCATED; - /* * unlock the table */ ossl_ht_write_unlock(fuzzer_table); /* - * Now check to make sure we did the right thing - */ - OPENSSL_assert(rc == rc_prediction); - - /* - * successful insertion if there wasn't a conflict + * mark the entry as being allocated */ - if (rc_prediction == 1) + if (rc == 1) { + valptr->flags |= FZ_FLAG_ALLOCATED; IS_REPLACE(op_flags) ? replacements++ : inserts++; + } break; case OP_DELETE: @@ -226,15 +203,6 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) /* lock the table */ ossl_ht_write_lock(fuzzer_table); - /* - * If the value to delete is not already allocated - * then we expect a miss in the delete - * i.e. we predict a return code of 0 instead - * of 1 - */ - if (!(valptr->flags & FZ_FLAG_ALLOCATED)) - rc_prediction = 0; - /* * do the delete */ @@ -245,22 +213,10 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) */ ossl_ht_write_unlock(fuzzer_table); - /* - * Now check to make sure we did the right thing - */ - OPENSSL_assert(rc == rc_prediction); - - /* - * once the unlock is done, the table rcu will have synced - * meaning the free function has run, so we can confirm now - * that the valptr is no longer allocated - */ - OPENSSL_assert(!(valptr->flags & FZ_FLAG_ALLOCATED)); - /* * successful deletion if there wasn't a conflict */ - if (rc_prediction == 1) + if (rc == 1) deletes++; break; @@ -301,24 +257,22 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) /* * Now check to make sure we did the right thing */ - OPENSSL_assert(lval == valptr); + if (valptr == NULL) + OPENSSL_assert(lval == NULL); + else + OPENSSL_assert(lval == NULL || lval == valptr); /* * if we expect a positive lookup, make sure that * we can use the _type and to_value functions */ - if (valptr != NULL) { + if (valptr != NULL && lval != NULL) { OPENSSL_assert(ossl_ht_fz_FUZZER_VALUE_type(v) == 1); v = ossl_ht_fz_FUZZER_VALUE_to_value(lval, &tv); OPENSSL_assert(v->value == lval); - } - - /* - * successful lookup if we didn't expect a miss - */ - if (valptr != NULL) lookups++; + } break; @@ -336,17 +290,17 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) * lock the table */ ossl_ht_write_lock(fuzzer_table); - ossl_ht_flush(fuzzer_table); + rc = ossl_ht_flush(fuzzer_table); ossl_ht_write_unlock(fuzzer_table); /* * now check to make sure everything is free */ - for (i = 0; i < USHRT_MAX; i++) - OPENSSL_assert((prediction_table[i].flags & FZ_FLAG_ALLOCATED) == 0); - - /* good flush */ - flushes++; + if (rc == 1) { + for (i = 0; i < USHRT_MAX; i++) + OPENSSL_assert((prediction_table[i].flags & FZ_FLAG_ALLOCATED) == 0); + flushes++; + } break; case OP_FOREACH: @@ -372,11 +326,11 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) rc_prediction = 1; htvlist = ossl_ht_filter(fuzzer_table, 1, filter_iterator, &keyval); - - OPENSSL_assert(htvlist->list_len == (size_t)rc_prediction); - - ossl_ht_value_list_free(htvlist); - filters++; + if (htvlist != NULL) { + OPENSSL_assert(htvlist->list_len == (size_t)rc_prediction); + ossl_ht_value_list_free(htvlist); + filters++; + } break; default: diff --git a/fuzz/ml-dsa.c b/fuzz/ml-dsa.c index 094af9096a2..e56a023e467 100644 --- a/fuzz/ml-dsa.c +++ b/fuzz/ml-dsa.c @@ -254,6 +254,10 @@ static int keygen_ml_dsa_real_key_helper(uint8_t **buf, size_t *len, ret = 1; err: + if (!ret) { + EVP_PKEY_free(*key); + *key = NULL; + } EVP_PKEY_CTX_free(ctx); return ret; } @@ -659,7 +663,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) /* And run our setup/doit/cleanup sequence */ if (ops[operation].setup != NULL) ops[operation].setup(&buffer_cursor, &len, &in1, &in2); - if (ops[operation].doit != NULL) + if (ops[operation].doit != NULL && in1 != NULL) ops[operation].doit(&buffer_cursor, &len, in1, in2, &out1, &out2); if (ops[operation].cleanup != NULL) ops[operation].cleanup(in1, in2, out1, out2); diff --git a/fuzz/ml-kem.c b/fuzz/ml-kem.c index 6e3aed8b23c..dfd4faf6dcc 100644 --- a/fuzz/ml-kem.c +++ b/fuzz/ml-kem.c @@ -650,7 +650,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) */ if (ops[operation].setup != NULL) ops[operation].setup(&buffer_cursor, &len, &in1, &in2); - if (ops[operation].doit != NULL) + if (ops[operation].doit != NULL && in1 != NULL) ops[operation].doit(&buffer_cursor, &len, in1, in2, &out1, &out2); if (ops[operation].cleanup != NULL) ops[operation].cleanup(in1, in2, out1, out2); diff --git a/fuzz/pem.c b/fuzz/pem.c index a8a1d810f0f..a2da9820a72 100644 --- a/fuzz/pem.c +++ b/fuzz/pem.c @@ -31,7 +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, (int)(len - 1)) == len - 1); + if (in == NULL) { + ERR_clear_error(); + return 0; + } + if ((size_t)BIO_write(in, buf + 1, (int)(len - 1)) != len - 1) { + BIO_free(in); + ERR_clear_error(); + 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. */ BIO_write(in, name, (int)strlen(name)); diff --git a/fuzz/pkcs12.c b/fuzz/pkcs12.c index 3bc9b5f7d70..74e2b6dd8aa 100644 --- a/fuzz/pkcs12.c +++ b/fuzz/pkcs12.c @@ -39,7 +39,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, (int)len) == len); + if (in == NULL) { + ERR_clear_error(); + return 0; + } + if ((size_t)BIO_write(in, buf, (int)len) != len) { + BIO_free(in); + ERR_clear_error(); + return 0; + } p12 = d2i_PKCS12_bio(in, NULL); if (p12 != NULL) { PKCS12_verify_mac(p12, NULL, 0); diff --git a/fuzz/provider.c b/fuzz/provider.c index e3acf3e4707..bc45489a2f0 100644 --- a/fuzz/provider.c +++ b/fuzz/provider.c @@ -304,6 +304,7 @@ static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *l if (!read_int(buf, len, &use_param)) { use_param = OPENSSL_malloc(sizeof(uint64_t)); if (use_param == NULL) { + free_params(fuzzed_parameters); OPENSSL_free(fuzzed_parameters); return NULL; } @@ -315,6 +316,7 @@ static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *l if (strcmp(param->key, OSSL_KDF_PARAM_ITER) == 0) { p_value_int = OPENSSL_malloc(sizeof(ITERS)); if (p_value_int == NULL) { + free_params(fuzzed_parameters); OPENSSL_free(fuzzed_parameters); OPENSSL_free(use_param); return NULL; @@ -323,6 +325,7 @@ static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *l } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_N) == 0) { p_value_int = OPENSSL_malloc(sizeof(ITERS)); if (p_value_int == NULL) { + free_params(fuzzed_parameters); OPENSSL_free(fuzzed_parameters); OPENSSL_free(use_param); return NULL; @@ -331,6 +334,7 @@ static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *l } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_R) == 0) { p_value_int = OPENSSL_malloc(sizeof(BLOCKSIZE)); if (p_value_int == NULL) { + free_params(fuzzed_parameters); OPENSSL_free(fuzzed_parameters); OPENSSL_free(use_param); return NULL; @@ -339,6 +343,7 @@ static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *l } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_P) == 0) { p_value_int = OPENSSL_malloc(sizeof(BLOCKSIZE)); if (p_value_int == NULL) { + free_params(fuzzed_parameters); OPENSSL_free(fuzzed_parameters); OPENSSL_free(use_param); return NULL; @@ -347,6 +352,7 @@ static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *l } else if (!*use_param || !read_int(buf, len, &p_value_int)) { p_value_int = OPENSSL_malloc(sizeof(int64_t)); if (p_value_int == NULL) { + free_params(fuzzed_parameters); OPENSSL_free(fuzzed_parameters); OPENSSL_free(use_param); return NULL; @@ -362,6 +368,7 @@ static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *l if (strcmp(param->key, OSSL_KDF_PARAM_ITER) == 0) { p_value_uint = OPENSSL_malloc(sizeof(UITERS)); if (p_value_uint == NULL) { + free_params(fuzzed_parameters); OPENSSL_free(fuzzed_parameters); OPENSSL_free(use_param); return NULL; @@ -370,6 +377,7 @@ static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *l } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_N) == 0) { p_value_uint = OPENSSL_malloc(sizeof(UITERS)); if (p_value_uint == NULL) { + free_params(fuzzed_parameters); OPENSSL_free(fuzzed_parameters); OPENSSL_free(use_param); return NULL; @@ -378,6 +386,7 @@ static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *l } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_R) == 0) { p_value_uint = OPENSSL_malloc(sizeof(UBLOCKSIZE)); if (p_value_uint == NULL) { + free_params(fuzzed_parameters); OPENSSL_free(fuzzed_parameters); OPENSSL_free(use_param); return NULL; @@ -386,6 +395,7 @@ static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *l } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_P) == 0) { p_value_uint = OPENSSL_malloc(sizeof(UBLOCKSIZE)); if (p_value_uint == NULL) { + free_params(fuzzed_parameters); OPENSSL_free(fuzzed_parameters); OPENSSL_free(use_param); return NULL; @@ -394,6 +404,7 @@ static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *l } else if (!*use_param || !read_uint(buf, len, &p_value_uint)) { p_value_uint = OPENSSL_malloc(sizeof(uint64_t)); if (p_value_uint == NULL) { + free_params(fuzzed_parameters); OPENSSL_free(fuzzed_parameters); OPENSSL_free(use_param); return NULL; @@ -409,6 +420,7 @@ static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *l if (!*use_param || !read_double(buf, len, &p_value_double)) { p_value_double = OPENSSL_malloc(sizeof(double)); if (p_value_double == NULL) { + free_params(fuzzed_parameters); OPENSSL_free(fuzzed_parameters); OPENSSL_free(use_param); return NULL; diff --git a/fuzz/quic-client.c b/fuzz/quic-client.c index 851ecc5cc9f..e75390ad602 100644 --- a/fuzz/quic-client.c +++ b/fuzz/quic-client.c @@ -77,6 +77,8 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) if (client == NULL) goto end; + allstreams[0] = stream = client; + fake_now = ossl_ms2time(1); if (!ossl_quic_set_override_now_cb(client, fake_now_cb, NULL)) goto end; @@ -90,7 +92,8 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) if (!BIO_ADDR_rawmake(peer_addr, AF_INET, &ina, sizeof(ina), htons(4433))) goto end; - SSL_set_tlsext_host_name(client, "localhost"); + if (SSL_set_tlsext_host_name(client, "localhost") != 1) + goto end; in = BIO_new(BIO_s_dgram_mem()); if (in == NULL) goto end; @@ -116,7 +119,6 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) 0)) goto end; - allstreams[0] = stream = client; for (;;) { size_t size; uint64_t nxtpktms = 0; diff --git a/fuzz/quic-srtm.c b/fuzz/quic-srtm.c index a7897da7103..6e152299e1b 100644 --- a/fuzz/quic-srtm.c +++ b/fuzz/quic-srtm.c @@ -77,9 +77,9 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) sizeof(arg_token.token))) continue; /* just stop */ - ossl_quic_srtm_add(srtm, (void *)(uintptr_t)arg_opaque, - arg_seq_num, &arg_token); - ossl_quic_srtm_check(srtm); + if (ossl_quic_srtm_add(srtm, (void *)(uintptr_t)arg_opaque, + arg_seq_num, &arg_token)) + ossl_quic_srtm_check(srtm); break; case CMD_REMOVE: @@ -87,17 +87,17 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) || !PACKET_get_net_8(&pkt, &arg_seq_num)) continue; /* just stop */ - ossl_quic_srtm_remove(srtm, (void *)(uintptr_t)arg_opaque, - arg_seq_num); - ossl_quic_srtm_check(srtm); + if (ossl_quic_srtm_remove(srtm, (void *)(uintptr_t)arg_opaque, + arg_seq_num)) + ossl_quic_srtm_check(srtm); break; case CMD_CULL: if (!PACKET_get_net_8(&pkt, &arg_opaque)) continue; /* just stop */ - ossl_quic_srtm_cull(srtm, (void *)(uintptr_t)arg_opaque); - ossl_quic_srtm_check(srtm); + if (ossl_quic_srtm_cull(srtm, (void *)(uintptr_t)arg_opaque)) + ossl_quic_srtm_check(srtm); break; case CMD_LOOKUP: @@ -106,9 +106,9 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) || !PACKET_get_net_8(&pkt, &arg_idx)) continue; /* just stop */ - ossl_quic_srtm_lookup(srtm, &arg_token, (size_t)arg_idx, - NULL, NULL); - ossl_quic_srtm_check(srtm); + if (ossl_quic_srtm_lookup(srtm, &arg_token, (size_t)arg_idx, + NULL, NULL)) + ossl_quic_srtm_check(srtm); break; default: diff --git a/fuzz/server.c b/fuzz/server.c index 1723cecda51..740ade8513d 100644 --- a/fuzz/server.c +++ b/fuzz/server.c @@ -25,6 +25,7 @@ #include #include "fuzzer.h" +#ifndef OPENSSL_NO_DEPRECATED_3_0 static const uint8_t kCertificateDER[] = { 0x30, 0x82, 0x02, 0xff, 0x30, 0x82, 0x01, 0xe7, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x11, 0x00, @@ -125,7 +126,6 @@ static const uint8_t kCertificateDER[] = { 0x76, 0x8a, 0xbb }; -#ifndef OPENSSL_NO_DEPRECATED_3_0 static const uint8_t kRSAPrivateKeyDER[] = { 0x30, 0x82, 0x04, 0xa5, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xce, 0x47, 0xcb, 0x11, @@ -281,7 +281,6 @@ static const uint8_t kRSAPrivateKeyDER[] = { #endif #ifndef OPENSSL_NO_EC -#ifndef OPENSSL_NO_DEPRECATED_3_0 /* * -----BEGIN EC PRIVATE KEY----- * MHcCAQEEIJLyl7hJjpQL/RhP1x2zS79xdiPJQB683gWeqcqHPeZkoAoGCCqGSM49 @@ -310,7 +309,6 @@ static const char ECDSAPrivateKeyPEM[] = { 0x4e, 0x44, 0x20, 0x45, 0x43, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a }; -#endif /* * -----BEGIN CERTIFICATE----- @@ -373,7 +371,7 @@ static const char ECDSACertPEM[] = { }; #endif -#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) +#ifndef OPENSSL_NO_DSA /* * -----BEGIN DSA PRIVATE KEY----- * MIIBuwIBAAKBgQDdkFKzNABLOha7Eqj7004+p5fhtR6bxpujToMmSZTYi8igVVXP @@ -593,139 +591,155 @@ time_t time(time_t *t) TIME_IMPL(t) return 1; } +#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DSA) +static int use_pem_privkey(SSL_CTX *ctx, const void *pem, size_t pem_len) +{ + BIO *bio_buf; + EVP_PKEY *pkey; + int rv = 0; + + bio_buf = BIO_new(BIO_s_mem()); + if (bio_buf == NULL) + return 0; + if ((size_t)BIO_write(bio_buf, pem, (int)pem_len) != pem_len) { + BIO_free(bio_buf); + return 0; + } + pkey = PEM_read_bio_PrivateKey(bio_buf, NULL, NULL, NULL); + BIO_free(bio_buf); + if (pkey == NULL) + return 0; + if (SSL_CTX_use_PrivateKey(ctx, pkey) == 1) + rv = 1; + EVP_PKEY_free(pkey); + return rv; +} + +static int use_pem_cert(SSL_CTX *ctx, const void *pem, size_t pem_len) +{ + BIO *bio_buf; + X509 *cert; + int rv = 0; + + bio_buf = BIO_new(BIO_s_mem()); + if (bio_buf == NULL) + return 0; + if ((size_t)BIO_write(bio_buf, pem, (int)pem_len) != pem_len) { + BIO_free(bio_buf); + return 0; + } + cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); + BIO_free(bio_buf); + if (cert == NULL) + return 0; + if (SSL_CTX_use_certificate(ctx, cert) == 1) + rv = 1; + X509_free(cert); + return rv; +} +#endif + int FuzzerTestOneInput(const uint8_t *buf, size_t len) { - SSL *server; + SSL *server = NULL; BIO *in; BIO *out; -#if !defined(OPENSSL_NO_EC) \ - || (!defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0)) - BIO *bio_buf; -#endif SSL_CTX *ctx; - int ret; #ifndef OPENSSL_NO_DEPRECATED_3_0 - RSA *privkey; -#endif const uint8_t *bufp; -#if !defined(OPENSSL_NO_DEPRECATED_3_0) - EVP_PKEY *pkey; -#endif - X509 *cert; -#ifndef OPENSSL_NO_DEPRECATED_3_0 -#ifndef OPENSSL_NO_EC - EC_KEY *ecdsakey = NULL; -#endif -#endif -#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) - DSA *dsakey = NULL; + RSA *privkey = NULL; + EVP_PKEY *pkey = NULL; + X509 *cert = NULL; #endif uint8_t opt; + int ret; if (len < 2 || len > INT_MAX) return 0; - /* This only fuzzes the initial flow from the client so far. */ ctx = SSL_CTX_new(TLS_method()); - OPENSSL_assert(ctx != NULL); - 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 (ctx == NULL) + return 0; + if (SSL_CTX_set_min_proto_version(ctx, 0) != 1) + goto end; + if (SSL_CTX_set_cipher_list(ctx, "ALL:eNULL:@SECLEVEL=0") != 1) + goto end; #ifndef OPENSSL_NO_DEPRECATED_3_0 /* RSA */ bufp = kRSAPrivateKeyDER; privkey = d2i_RSAPrivateKey(NULL, &bufp, sizeof(kRSAPrivateKeyDER)); - OPENSSL_assert(privkey != NULL); + if (privkey == NULL) + goto end; pkey = EVP_PKEY_new(); - OPENSSL_assert(pkey != NULL); - EVP_PKEY_assign_RSA(pkey, privkey); + if (pkey == NULL) { + RSA_free(privkey); + goto end; + } + if (!EVP_PKEY_assign_RSA(pkey, privkey)) { + /* assignment failed; pkey doesn't own privkey, clean both */ + RSA_free(privkey); + EVP_PKEY_free(pkey); + goto end; + } ret = SSL_CTX_use_PrivateKey(ctx, pkey); - OPENSSL_assert(ret == 1); EVP_PKEY_free(pkey); -#endif + if (ret != 1) + goto end; bufp = kCertificateDER; cert = d2i_X509(NULL, &bufp, sizeof(kCertificateDER)); - OPENSSL_assert(cert != NULL); + if (cert == NULL) + goto end; ret = SSL_CTX_use_certificate(ctx, cert); - OPENSSL_assert(ret == 1); X509_free(cert); + if (ret != 1) + goto end; +#endif #ifndef OPENSSL_NO_EC -#ifndef OPENSSL_NO_DEPRECATED_3_0 /* ECDSA */ - bio_buf = BIO_new(BIO_s_mem()); - OPENSSL_assert(bio_buf != NULL); - OPENSSL_assert((size_t)BIO_write(bio_buf, ECDSAPrivateKeyPEM, sizeof(ECDSAPrivateKeyPEM)) == sizeof(ECDSAPrivateKeyPEM)); - ecdsakey = PEM_read_bio_ECPrivateKey(bio_buf, NULL, NULL, NULL); - ERR_print_errors_fp(stderr); - OPENSSL_assert(ecdsakey != NULL); - BIO_free(bio_buf); - pkey = EVP_PKEY_new(); - OPENSSL_assert(pkey != NULL); - 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(bio_buf != NULL); - OPENSSL_assert((size_t)BIO_write(bio_buf, ECDSACertPEM, sizeof(ECDSACertPEM)) == sizeof(ECDSACertPEM)); - cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); - OPENSSL_assert(cert != NULL); - BIO_free(bio_buf); - ret = SSL_CTX_use_certificate(ctx, cert); - OPENSSL_assert(ret == 1); - X509_free(cert); + if (!use_pem_privkey(ctx, ECDSAPrivateKeyPEM, sizeof(ECDSAPrivateKeyPEM))) + goto end; + if (!use_pem_cert(ctx, ECDSACertPEM, sizeof(ECDSACertPEM))) + goto end; #endif -#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) +#ifndef OPENSSL_NO_DSA /* DSA */ - bio_buf = BIO_new(BIO_s_mem()); - OPENSSL_assert(bio_buf != NULL); - OPENSSL_assert((size_t)BIO_write(bio_buf, DSAPrivateKeyPEM, sizeof(DSAPrivateKeyPEM)) == sizeof(DSAPrivateKeyPEM)); - dsakey = PEM_read_bio_DSAPrivateKey(bio_buf, NULL, NULL, NULL); - ERR_print_errors_fp(stderr); - OPENSSL_assert(dsakey != NULL); - BIO_free(bio_buf); - pkey = EVP_PKEY_new(); - OPENSSL_assert(pkey != NULL); - 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(bio_buf != NULL); - OPENSSL_assert((size_t)BIO_write(bio_buf, DSACertPEM, sizeof(DSACertPEM)) == sizeof(DSACertPEM)); - cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); - OPENSSL_assert(cert != NULL); - BIO_free(bio_buf); - ret = SSL_CTX_use_certificate(ctx, cert); - OPENSSL_assert(ret == 1); - X509_free(cert); + if (!use_pem_privkey(ctx, DSAPrivateKeyPEM, sizeof(DSAPrivateKeyPEM))) + goto end; + if (!use_pem_cert(ctx, DSACertPEM, sizeof(DSACertPEM))) + goto end; #endif server = SSL_new(ctx); + if (server == NULL) + goto end; in = BIO_new(BIO_s_mem()); - OPENSSL_assert(in != NULL); + if (in == NULL) + goto end; out = BIO_new(BIO_s_mem()); - OPENSSL_assert(out != NULL); + if (out == NULL) { + BIO_free(in); + goto end; + } SSL_set_bio(server, in, out); SSL_set_accept_state(server); opt = (uint8_t)buf[len - 1]; len--; - OPENSSL_assert((size_t)BIO_write(in, buf, (int)len) == len); + if ((size_t)BIO_write(in, buf, (int)len) != len) + goto end; if ((opt & 0x01) != 0) { do { char early_buf[16384]; size_t early_len; - ret = SSL_read_early_data(server, early_buf, sizeof(early_buf), &early_len); + + ret = SSL_read_early_data(server, early_buf, sizeof(early_buf), + &early_len); if (ret != SSL_READ_EARLY_DATA_SUCCESS) break; @@ -741,6 +755,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) } } } +end: SSL_free(server); ERR_clear_error(); SSL_CTX_free(ctx); diff --git a/fuzz/slh-dsa.c b/fuzz/slh-dsa.c index 17238bcf8b3..0f78a01da89 100644 --- a/fuzz/slh-dsa.c +++ b/fuzz/slh-dsa.c @@ -63,26 +63,32 @@ static EVP_PKEY *slh_dsa_gen_key(const char *name, uint32_t keysize, { EVP_PKEY_CTX *ctx; EVP_PKEY *new = NULL; - int rc; ctx = EVP_PKEY_CTX_new_from_name(NULL, name, NULL); - OPENSSL_assert(ctx != NULL); + if (ctx == NULL) + return NULL; if (params != NULL) { new = EVP_PKEY_new(); - OPENSSL_assert(EVP_PKEY_fromdata_init(ctx)); - if (*param_broken) { - rc = EVP_PKEY_fromdata(ctx, &new, EVP_PKEY_KEYPAIR, params); - OPENSSL_assert(rc == 0); + if (new == NULL) + goto out; + if (!EVP_PKEY_fromdata_init(ctx)) { + EVP_PKEY_free(new); + new = NULL; + goto out; + } + if (EVP_PKEY_fromdata(ctx, &new, EVP_PKEY_KEYPAIR, params) != 1) { EVP_PKEY_free(new); new = NULL; - } else { - OPENSSL_assert(EVP_PKEY_fromdata(ctx, &new, EVP_PKEY_KEYPAIR, params) == 1); } goto out; } - OPENSSL_assert(EVP_PKEY_keygen_init(ctx)); - OPENSSL_assert(EVP_PKEY_generate(ctx, &new)); + if (!EVP_PKEY_keygen_init(ctx)) + goto out; + if (!EVP_PKEY_generate(ctx, &new)) { + EVP_PKEY_free(new); + new = NULL; + } out: EVP_PKEY_CTX_free(ctx); @@ -221,9 +227,10 @@ static void slh_dsa_gen_key_with_params(uint8_t **buf, size_t *len, *buf = consume_uint8t(*buf, len, &selector); keytype = select_keytype(selector, &keysize); - RAND_bytes(pubbuf, PARAM_BUF_SZ); - RAND_bytes(prvbuf, PARAM_BUF_SZ); - RAND_bytes(sdbuf, PARAM_BUF_SZ); + if (!RAND_bytes(pubbuf, PARAM_BUF_SZ) + || !RAND_bytes(prvbuf, PARAM_BUF_SZ) + || !RAND_bytes(sdbuf, PARAM_BUF_SZ)) + return; /* * select an invalid length if the buffer 0th bit is one @@ -260,11 +267,6 @@ static void slh_dsa_gen_key_with_params(uint8_t **buf, size_t *len, params[2] = OSSL_PARAM_construct_end(); *out1 = (void *)slh_dsa_gen_key(keytype, keysize, params, &broken); - - if (broken) - OPENSSL_assert(*out1 == NULL); - else - OPENSSL_assert(*out1 != NULL); return; } @@ -319,7 +321,6 @@ static void slh_dsa_sign_verify(uint8_t **buf, size_t *len, void *key1, OSSL_PARAM params[4]; int paramidx = 0; int intval1, intval2; - int expect_init_rc = 1; *buf = consume_uint8t(*buf, len, &selector); if (*buf == NULL) @@ -340,10 +341,6 @@ static void slh_dsa_sign_verify(uint8_t **buf, size_t *len, void *key1, msg = (unsigned char *)*buf; msg_len = *len; - /* if msg_len > 255, sign_message_init will fail */ - if (msg_len > 255 && (selector & 0x1) != 0) - expect_init_rc = 0; - *len = 0; if (selector & 0x1) @@ -365,33 +362,39 @@ static void slh_dsa_sign_verify(uint8_t **buf, size_t *len, void *key1, params[paramidx] = OSSL_PARAM_construct_end(); key = (void *)slh_dsa_gen_key(keytype, keylen, NULL, 0); - OPENSSL_assert(key != NULL); + if (key == NULL) + return; *out1 = key; /* for cleanup */ ctx = EVP_PKEY_CTX_new_from_pkey(NULL, key, NULL); - OPENSSL_assert(ctx != NULL); + if (ctx == NULL) + goto out; sig_alg = EVP_SIGNATURE_fetch(NULL, keytype, NULL); - OPENSSL_assert(sig_alg != NULL); + if (sig_alg == NULL) + goto out; - OPENSSL_assert(EVP_PKEY_sign_message_init(ctx, sig_alg, params) == expect_init_rc); /* * the context_string parameter can be no more than 255 bytes, so if - * our random input buffer is greater than that, we expect failure above, - * which we check for. In that event, there's nothing more we can do here - * so bail out + * our random input buffer is greater than that, sign_message_init will + * fail, in which case there's nothing more we can do here so bail out */ - if (expect_init_rc == 0) + if (EVP_PKEY_sign_message_init(ctx, sig_alg, params) != 1) goto out; - OPENSSL_assert(EVP_PKEY_sign(ctx, NULL, &sig_len, msg, msg_len)); + if (EVP_PKEY_sign(ctx, NULL, &sig_len, msg, msg_len) != 1) + goto out; sig = OPENSSL_zalloc(sig_len); - OPENSSL_assert(sig != NULL); + if (sig == NULL) + goto out; - OPENSSL_assert(EVP_PKEY_sign(ctx, sig, &sig_len, msg, msg_len)); + if (EVP_PKEY_sign(ctx, sig, &sig_len, msg, msg_len) != 1) + goto out; - OPENSSL_assert(EVP_PKEY_verify_message_init(ctx, sig_alg, params)); - OPENSSL_assert(EVP_PKEY_verify(ctx, sig, sig_len, msg, msg_len)); + if (EVP_PKEY_verify_message_init(ctx, sig_alg, params) != 1) + goto out; + if (EVP_PKEY_verify(ctx, sig, sig_len, msg, msg_len) != 1) + fprintf(stderr, "Failed to verify message\n"); out: OPENSSL_free(sig); @@ -417,32 +420,34 @@ out: static void slh_dsa_export_import(uint8_t **buf, size_t *len, void *key1, void *key2, void **out1, void **out2) { - int rc; EVP_PKEY *alice = (EVP_PKEY *)key1; EVP_PKEY *bob = (EVP_PKEY *)key2; EVP_PKEY *new = NULL; EVP_PKEY_CTX *ctx = NULL; OSSL_PARAM *params = NULL; - OPENSSL_assert(EVP_PKEY_todata(alice, EVP_PKEY_KEYPAIR, ¶ms) == 1); + if (alice == NULL || bob == NULL) + return; + + if (!EVP_PKEY_todata(alice, EVP_PKEY_KEYPAIR, ¶ms)) + goto alice_done; ctx = EVP_PKEY_CTX_new_from_pkey(NULL, alice, NULL); - OPENSSL_assert(ctx != NULL); + if (ctx == NULL) + goto alice_done; - OPENSSL_assert(EVP_PKEY_fromdata_init(ctx)); + if (!EVP_PKEY_fromdata_init(ctx)) + goto alice_done; new = EVP_PKEY_new(); - OPENSSL_assert(new != NULL); - OPENSSL_assert(EVP_PKEY_fromdata(ctx, &new, EVP_PKEY_KEYPAIR, params) == 1); + if (new == NULL) + goto alice_done; + if (EVP_PKEY_fromdata(ctx, &new, EVP_PKEY_KEYPAIR, params) != 1) + goto alice_done; - /* - * EVP_PKEY returns: - * 1 if the keys are equivalent - * 0 if the keys are not equivalent - * -1 if the key types are different - * -2 if the operation is not supported - */ - OPENSSL_assert(EVP_PKEY_eq(alice, new) == 1); + (void)EVP_PKEY_eq(alice, new); + +alice_done: EVP_PKEY_free(new); EVP_PKEY_CTX_free(ctx); OSSL_PARAM_free(params); @@ -450,26 +455,26 @@ static void slh_dsa_export_import(uint8_t **buf, size_t *len, void *key1, ctx = NULL; new = NULL; - OPENSSL_assert(EVP_PKEY_todata(bob, EVP_PKEY_KEYPAIR, ¶ms) == 1); + if (!EVP_PKEY_todata(bob, EVP_PKEY_KEYPAIR, ¶ms)) + goto bob_done; ctx = EVP_PKEY_CTX_new_from_pkey(NULL, bob, NULL); - OPENSSL_assert(ctx != NULL); + if (ctx == NULL) + goto bob_done; - OPENSSL_assert(EVP_PKEY_fromdata_init(ctx)); + if (!EVP_PKEY_fromdata_init(ctx)) + goto bob_done; new = EVP_PKEY_new(); - OPENSSL_assert(new != NULL); - OPENSSL_assert(EVP_PKEY_fromdata(ctx, &new, EVP_PKEY_KEYPAIR, params) == 1); + if (new == NULL) + goto bob_done; + if (EVP_PKEY_fromdata(ctx, &new, EVP_PKEY_KEYPAIR, params) != 1) + goto bob_done; - OPENSSL_assert(EVP_PKEY_eq(bob, new) == 1); - - /* - * Depending on the types of eys that get generated - * we might get a simple non-equivalence or a type mismatch here - */ - rc = EVP_PKEY_eq(alice, new); - OPENSSL_assert(rc == 0 || rc == -1); + (void)EVP_PKEY_eq(bob, new); + (void)EVP_PKEY_eq(alice, new); +bob_done: EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(new); OSSL_PARAM_free(params); @@ -589,7 +594,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) */ if (ops[operation].setup != NULL) ops[operation].setup(&buffer_cursor, &len, &in1, &in2); - if (ops[operation].doit != NULL) + if (ops[operation].doit != NULL && in1 != NULL) ops[operation].doit(&buffer_cursor, &len, in1, in2, &out1, &out2); if (ops[operation].cleanup != NULL) ops[operation].cleanup(in1, in2, out1, out2); diff --git a/fuzz/smime.c b/fuzz/smime.c index b55a1ef74b8..ab68cb0165d 100644 --- a/fuzz/smime.c +++ b/fuzz/smime.c @@ -21,8 +21,18 @@ int FuzzerInitialize(int *argc, char ***argv) int FuzzerTestOneInput(const uint8_t *buf, size_t len) { - BIO *b = BIO_new_mem_buf(buf, (int)len); - PKCS7 *p7 = SMIME_read_PKCS7(b, NULL); + BIO *b; + PKCS7 *p7; + + if (len > INT_MAX) + return 0; + + b = BIO_new_mem_buf(buf, (int)len); + if (b == NULL) { + ERR_clear_error(); + return 0; + } + p7 = SMIME_read_PKCS7(b, NULL); if (p7 != NULL) { STACK_OF(PKCS7_SIGNER_INFO) *p7si = PKCS7_get_signer_info(p7); diff --git a/fuzz/v3name.c b/fuzz/v3name.c index 9a525e6f48b..87fd8c14717 100644 --- a/fuzz/v3name.c +++ b/fuzz/v3name.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include "internal/nelem.h" @@ -23,8 +24,11 @@ int FuzzerTestOneInput(const uint8_t *data, size_t size) { GENERAL_NAME *namesa; GENERAL_NAME *namesb; - const unsigned char *derp = data; + + if (size > LONG_MAX) + return 0; + /* * We create two versions of each GENERAL_NAME so that we ensure when * we compare them they are always different pointers. @@ -32,11 +36,11 @@ int FuzzerTestOneInput(const uint8_t *data, size_t size) namesa = d2i_GENERAL_NAME(NULL, &derp, (long)size); derp = data; namesb = d2i_GENERAL_NAME(NULL, &derp, (long)size); - GENERAL_NAME_cmp(namesa, namesb); - if (namesa != NULL) - GENERAL_NAME_free(namesa); - if (namesb != NULL) - GENERAL_NAME_free(namesb); + if (namesa != NULL && namesb != NULL) + GENERAL_NAME_cmp(namesa, namesb); + GENERAL_NAME_free(namesa); + GENERAL_NAME_free(namesb); + ERR_clear_error(); return 0; } diff --git a/fuzz/x509.c b/fuzz/x509.c index 68249b48dbf..a10e8c00677 100644 --- a/fuzz/x509.c +++ b/fuzz/x509.c @@ -99,7 +99,8 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) if (ctx == NULL) goto err; - X509_STORE_CTX_init(ctx, store, x509_1, NULL); + if (!X509_STORE_CTX_init(ctx, store, x509_1, NULL)) + goto err; if (crl != NULL) { crls = sk_X509_CRL_new_null();