Repository navigation
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The key-share failure cleanup can still leak nonblocking contexts, and its X448 path remains untested.
Review effort: Balanced
Findings: 3
Open (4)
What changed in this PR
This PR hardens TLS and DTLS API tests against allocation failures and adds cleanup for key-share entries when an extension-list allocation fails.
Changes:
- Stop DTLS tests from using objects whose constructors failed, and clear freed TLS test pointers.
- Free key-share entries by group when
TLSX_Pushfails.
| File | Description |
|---|---|
tests/api/test_tls13.c |
Clears freed TLS test pointers. |
tests/api/test_tls_parse.c |
Clears freed pointers and adds key-share failure cleanup. |
tests/api/test_ssl_cert.c |
Returns early when DTLS test constructors fail. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Reply to the Copilot review. The three nonblocking leaks are handled in a8f40dc. On a failed TLSX_Push, the FFDHE path frees DhKey.nb before wc_FreeDhKey, the X25519 path frees nb_ctx before wc_curve25519_free, and the ECC path frees nb_ctx before wc_ecc_free. Each free is under the same macros as TLSX_KeyShare_FreeAll. The private-key wipe calls wc_ForceZero, which is the symbol this test file can link. The missing coverage is also in a8f40dc. test_TLSX_KeyShare_gen generates an FFDHE 2048, X25519, X448, and secp256r1 key, fails the next allocation (the list node), and frees that entry. 15a0f58 puts that helper under USE_WOLFSSL_MEMORY. wolfSSL_GetAllocators and wolfSSL_SetAllocators are built only with that macro, and White-box smoke reported the unguarded calls. The WOLFSSL_TRACK_MEMORY make check failure is a 30 minute timeout of all-noasm-wolfentropy. That log shows 0 failed tests. The sibling all-wolfentropy config in the same job also ran far past its budget. Those timeouts are not an assertion failure from this change. MemBrowse measures IDE/GCC-ARM WolfCryptTest. This pull request only changes tests/api, and that image does not compile those files. The report on 4140c96 found no size change against the same base. |
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11608
Scan targets checked: wolfssl-bugs
Coverage: 2 of 3 in-scope changed file(s) opened by the reviewer; not opened: tests/api/test_ssl_cert.c
Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Reported findings require changes before merge.
Review tier: Lite
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11608
Scan targets checked: wolfssl-bugs
Coverage: 1 of 1 in-scope changed file(s) opened by the reviewer
Fenrir result: Approved ✅
No new issues found in the changed files.
Advisory only — this automated result does not count as a GitHub approval.
Review tier: Lite
Fenrir's latest completed scan found no issues; clearing the prior automated change request.
| kse->group = WOLFSSL_FFDHE_2048; | ||
| ExpectIntEQ(TLSX_KeyShare_GenKey(ssl, kse), 0); | ||
| ExpectNotNull(kse->pubKey); | ||
| ExpectIntEQ(test_tls_parse_free_kse_push_fail(ssl, kse), 0); |
There was a problem hiding this comment.
This test_tls_parse_free_kse_push_fail() is inside an Expect*() wrapper.
If kse is allocated, but an error happens later, then kse leaks.
There was a problem hiding this comment.
Fixed in 60ae2f9. The helper now runs before ExpectIntEQ. A failed GenKey or pubKey check still frees kse. The X25519, X448, and P-256 blocks use the same order.
| kse->group = WOLFSSL_ECC_X25519; | ||
| ExpectIntEQ(TLSX_KeyShare_GenKey(ssl, kse), 0); | ||
| ExpectNotNull(kse->pubKey); | ||
| ExpectIntEQ(test_tls_parse_free_kse_push_fail(ssl, kse), 0); |
There was a problem hiding this comment.
same, kse will leak when behind an Expect.*() gate on err.
There was a problem hiding this comment.
Fixed in 60ae2f9. This block calls the helper, then ExpectIntEQ checks the return value.
| ssl->heap, DYNAMIC_TYPE_TLSX)); | ||
| if (kse != NULL) { | ||
| XMEMSET(kse, 0, sizeof(*kse)); | ||
| kse->group = WOLFSSL_ECC_SECP256R1; |
There was a problem hiding this comment.
WOLFSSL_ECC_SECP256R1 is usually behind a combined define gate like
#ifdef HAVE_ECC
#if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
case WOLFSSL_ECC_SECP256R1:There was a problem hiding this comment.
Fixed in 60ae2f9. This block is now under HAVE_ECC, HAVE_ECC_KEY_EXPORT, !NO_ECC256 or HAVE_ALL_CURVES, !NO_ECC_SECP, and ECC_MIN_KEY_SZ <= 256. That matches the P-256 arm in TLSX_KeyShare_GenEccKey. The null-rng case in the same block uses that gate too.
|
Retest this please (apple-m1 test was still disrupted). |
ExpectNotNull skips the following wolfSSL_new when wolfSSL_CTX_new fails, so wolfSSL_free ran on the previous SSL. Clear both pointers after each free. Skip the DTLS guard calls when the constructor did not produce an object. Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
Once MEM_FAIL_CNT is hit, every later allocation fails. TLSX_Push then cannot take the peer entry, so test_TLSX_KeyShare_process leaked it. Free that entry directly. Clear the ServerHello test pointers after the first free so the next wolfSSL_free does not run twice. Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
The push-failure path called wc_ecc_free for every group other than X25519, so a live X448 key was freed as an ECC key. FFDHE, X25519, X448, and ECC now each use their own free. Drop the pointer clears in tests that were not failing under MEM_FAIL_CNT. Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
Call wc_ForceZero so this file builds where ForceZero is not in scope. Release the software-async buffers the same way TLSX_KeyShare_FreeAll does, and fail the list-node allocation for each generated key type. Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
wolfSSL_GetAllocators and wolfSSL_SetAllocators are built only when USE_WOLFSSL_MEMORY is set. The new helper called them without that guard, so the API guard check failed. Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
After an Expect fails, the next ExpectNotNull does not assign kse, so the push-fail block still named the entry just freed. Clear kse first. Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
ExpectIntEQ does not call its argument after a failure, so the push-fail helper never freed the entry. Call it first, then check the result. Run the P-256 cases only when GenEccKey accepts that group. Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
60ae2f9 to
41588f0
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11608
Scan targets checked: wolfssl-bugs
Coverage: 1 of 1 in-scope changed file(s) opened by the reviewer
Fenrir result: Approved ✅
No new issues found in the changed files.
Advisory only — this automated result does not count as a GitHub approval.
Review tier: Lite


Summary
wolfSSL_CTX_neworwolfSSL_newfails, so a later call does not use a null object.sslandctxafter each free in the TLS extension tests that segfaulted when the nextwolfSSL_CTX_newfailed underMEM_FAIL_CNT.TLSX_Pushcannot allocate the key-share list node, free the entry with the function for its group (FFDHE, X25519, X448, or ECC) instead of leaking it or callingwc_ecc_freeon the wrong key.Test plan
--enable-all,-DWOLFSSL_MEM_FAIL_COUNT) and the nine failing indexes: exit 1, free count equal to allocation count, no segmentation fault.MEM_FAIL_CNTon an X448 key share whoseTLSX_Pushis the failed allocation: no segmentation fault, free count equal to allocation count.