From eff6450239ee4a776fbdc615ea4195abac1e4de6 Mon Sep 17 00:00:00 2001 From: Sameeh Jubran Date: Thu, 6 Aug 2026 11:15:24 +0300 Subject: [PATCH] Fix mem-fail nightly crashes (jenkins-supervisor #501) The mem-fail Jenkins job fails allocation N via MEM_FAIL_CNT and treats segfault/abort as product findings. Several unit tests still touched NULL or uninitialised state after an Expect* failure, so the job went red even when the library returned a clean error. - test_wolfSSL_X509_VERIFY_PARAM (shard 2, fail at 2/3 and 3/3): Guard bare paramTo/paramFrom writes after X509_VERIFY_PARAM_new() returns NULL. - test_wc_Sakke_FeatureCoverage / DecisionCoverage (shards 0 and 3): Zero-init rng/key/key2 so FreeSakkeKey is not called on stack garbage when init fails. Make wc_FreeSakkeKey clear freed pointers so a second free after a failed init is safe. - test_wolfSSL_Tls13_ECH_wire_sni (shard 0, fail around 3147/6295): Do not dereference test_ctx.c_ctx when memio setup failed. Signed-off-by: Sameeh Jubran --- tests/api.c | 2 +- tests/api/test_ossl_x509_vp.c | 22 ++++++++++++++-------- tests/api/test_sakke.c | 4 ++++ wolfcrypt/src/sakke.c | 7 +++++++ 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/tests/api.c b/tests/api.c index d13c0ff0147..5609a2a09f6 100644 --- a/tests/api.c +++ b/tests/api.c @@ -16325,7 +16325,7 @@ static int test_wolfSSL_Tls13_ECH_wire_sni_ex(int accept, int useCtx) wolfSSL_SNI_GetRequest(test_ctx.s_ssl, WOLFSSL_SNI_HOST_NAME, &sniName); ExpectStrEQ((const char*)sniName, expectedSni); /* verify the ctx always has the private SNI */ - if (useCtx) { + if (useCtx && EXPECT_SUCCESS() && (test_ctx.c_ctx != NULL)) { sniName = NULL; TLSX_SNI_GetRequest(test_ctx.c_ctx->extensions, WOLFSSL_SNI_HOST_NAME, &sniName, 1); diff --git a/tests/api/test_ossl_x509_vp.c b/tests/api/test_ossl_x509_vp.c index 4cf338c526b..f3b463b36e2 100644 --- a/tests/api/test_ossl_x509_vp.c +++ b/tests/api/test_ossl_x509_vp.c @@ -155,8 +155,10 @@ int test_wolfSSL_X509_VERIFY_PARAM(void) ExpectIntEQ(X509_VERIFY_PARAM_set1_host(paramTo, testhostName2, (int)XSTRLEN(testhostName2)), 1); ExpectIntEQ(X509_VERIFY_PARAM_set1_ip_asc(paramTo, testIPv4), 1); - paramTo->inherit_flags = X509_VP_FLAG_ONCE; - paramFrom->inherit_flags = 0; + if ((paramTo != NULL) && (paramFrom != NULL)) { + paramTo->inherit_flags = X509_VP_FLAG_ONCE; + paramFrom->inherit_flags = 0; + } ExpectIntEQ(X509_VERIFY_PARAM_inherit(paramTo, paramFrom), 1); ExpectIntEQ(paramTo->inherit_flags, 0); ExpectIntEQ(0, XSTRNCMP(paramTo->hostName, testhostName2, @@ -164,17 +166,21 @@ int test_wolfSSL_X509_VERIFY_PARAM(void) ExpectIntEQ(0, XSTRNCMP(paramTo->ipasc, testIPv4, WOLFSSL_MAX_IPSTR)); /* check_time should not be copied when already set unless overwrite */ - XMEMSET(paramTo, 0, sizeof(X509_VERIFY_PARAM)); - XMEMSET(paramFrom, 0, sizeof(X509_VERIFY_PARAM)); - paramTo->check_time = 11; - paramTo->flags = WOLFSSL_USE_CHECK_TIME; - paramFrom->check_time = 22; + if ((paramTo != NULL) && (paramFrom != NULL)) { + XMEMSET(paramTo, 0, sizeof(X509_VERIFY_PARAM)); + XMEMSET(paramFrom, 0, sizeof(X509_VERIFY_PARAM)); + paramTo->check_time = 11; + paramTo->flags = WOLFSSL_USE_CHECK_TIME; + paramFrom->check_time = 22; + } ExpectIntEQ(X509_VERIFY_PARAM_inherit(paramTo, paramFrom), 1); ExpectTrue(paramTo->check_time == 11); ExpectIntEQ(paramTo->flags & WOLFSSL_USE_CHECK_TIME, WOLFSSL_USE_CHECK_TIME); - paramTo->inherit_flags = X509_VP_FLAG_OVERWRITE; + if (paramTo != NULL) { + paramTo->inherit_flags = X509_VP_FLAG_OVERWRITE; + } ExpectIntEQ(X509_VERIFY_PARAM_inherit(paramTo, paramFrom), 1); ExpectTrue(paramTo->check_time == 22); ExpectIntEQ(paramTo->flags & WOLFSSL_USE_CHECK_TIME, 0); diff --git a/tests/api/test_sakke.c b/tests/api/test_sakke.c index 0cc56c9cd37..78d4a8d8239 100644 --- a/tests/api/test_sakke.c +++ b/tests/api/test_sakke.c @@ -158,6 +158,9 @@ int test_wc_Sakke_DecisionCoverage(void) byte encSsv[16]; int valid = 0; + XMEMSET(&rng, 0, sizeof(rng)); + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(&key2, 0, sizeof(key2)); /* idMax is used only to exercise the idSz == SAKKE_ID_MAX_SIZE boundary * (byte *length*, not magnitude) -- keep it numerically small so the * real EC scalar multiply it drives (in wc_MakeSakkePointI()/ @@ -676,6 +679,7 @@ int test_wc_Sakke_FeatureCoverage(void) word32 pubKeySz2 = sizeof(pubKeyData2); int i; + XMEMSET(&rng, 0, sizeof(rng)); XMEMSET(&key, 0, sizeof(key)); XMEMSET(&key2, 0, sizeof(key2)); XMEMSET(ssvOrig, 0, sizeof(ssvOrig)); diff --git a/wolfcrypt/src/sakke.c b/wolfcrypt/src/sakke.c index a7b64e32a76..28a2e01bf08 100644 --- a/wolfcrypt/src/sakke.c +++ b/wolfcrypt/src/sakke.c @@ -202,26 +202,33 @@ void wc_FreeSakkeKey(SakkeKey* key) #ifdef WOLFCRYPT_SAKKE_CLIENT mp_free(&key->tmp.m2); #endif + key->mpInit = 0; } #ifdef WOLFCRYPT_SAKKE_CLIENT if (key->i.i != NULL) { wc_ecc_del_point_h(key->i.i, key->ecc.heap); + key->i.i = NULL; } if (key->rsk.rsk != NULL) { wc_ecc_del_point_h(key->rsk.rsk, key->ecc.heap); + key->rsk.rsk = NULL; } if (key->tmp.p3 != NULL) { wc_ecc_del_point_h(key->tmp.p3, key->ecc.heap); + key->tmp.p3 = NULL; } if (key->tmp.p2 != NULL) { wc_ecc_del_point_h(key->tmp.p2, key->ecc.heap); + key->tmp.p2 = NULL; } if (key->tmp.p1 != NULL) { wc_ecc_del_point_h(key->tmp.p1, key->ecc.heap); + key->tmp.p1 = NULL; } #endif if (params->base != NULL) { wc_ecc_del_point_h(params->base, key->ecc.heap); + params->base = NULL; } wc_ecc_free(&key->ecc); }