Skip to content

tests: fix mem-fail crashes and the key-share leak - #11608

Open
sameehj wants to merge 7 commits into
wolfSSL:masterfrom
sameehj:fix/mem-fail-null-deref
Open

sameehj wants to merge 7 commits into
wolfSSL:masterfrom
sameehj:fix/mem-fail-null-deref

Conversation

@sameehj

@sameehj sameehj commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Return from the DTLS API tests when wolfSSL_CTX_new or wolfSSL_new fails, so a later call does not use a null object.
  • Clear ssl and ctx after each free in the TLS extension tests that segfaulted when the next wolfSSL_CTX_new failed under MEM_FAIL_CNT.
  • When TLSX_Push cannot 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 calling wc_ecc_free on the wrong key.

Test plan

  • Nightly configure (--enable-all, -DWOLFSSL_MEM_FAIL_COUNT) and the nine failing indexes: exit 1, free count equal to allocation count, no segmentation fault.
  • MEM_FAIL_CNT on an X448 key share whose TLSX_Push is the failed allocation: no segmentation fault, free count equal to allocation count.
  • Confirm the tests that were not in the nightly errors are unchanged apart from the shared free helper.

Copilot AI balanced review requested due to automatic review settings September 30, 2026 13:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 Medium severity · 1 Low severity

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_Push fails.
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.

Comment thread tests/api/test_tls_parse.c Outdated
Comment thread tests/api/test_tls_parse.c Outdated
Comment thread tests/api/test_tls_parse.c Outdated
Comment thread tests/api/test_tls_parse.c
@sameehj

sameehj commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

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 wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread tests/api/test_tls_parse.c

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@wolfSSL-Fenrir-bot
wolfSSL-Fenrir-bot dismissed their stale review October 1, 2026 20:28

Fenrir's latest completed scan found no issues; clearing the prior automated change request.

@philljj philljj self-assigned this Oct 2, 2026
Comment thread tests/api/test_tls_parse.c Outdated
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);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread tests/api/test_tls_parse.c Outdated
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);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same, kse will leak when behind an Expect.*() gate on err.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@philljj philljj assigned sameehj and unassigned wolfSSL-Bot Oct 6, 2026
@philljj

philljj commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

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>
@sameehj
sameehj force-pushed the fix/mem-fail-null-deref branch from 60ae2f9 to 41588f0 Compare October 8, 2026 06:10
@sameehj
sameehj requested review from philljj and wolfSSL-Fenrir-bot and a balanced review from Copilot October 8, 2026 06:24
@sameehj sameehj assigned wolfSSL-Bot and unassigned sameehj Oct 9, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The changes consistently handle allocation failures and provide targeted coverage for the corrected cleanup paths.

0 open findings

4 resolved since last review

🧠 Review effort: Balanced

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants