Skip to content

Fenrir 15782: Allocate session memory from the CTX heap, not the SSL heap - #11899

Open
aidankeefe2022 wants to merge 1 commit into
wolfSSL:masterfrom
aidankeefe2022:ssl-sess-fenrir
Open

aidankeefe2022 wants to merge 1 commit into
wolfSSL:masterfrom
aidankeefe2022:ssl-sess-fenrir

Conversation

@aidankeefe2022

@aidankeefe2022 aidankeefe2022 commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Description

With WOLFSSL_STATIC_MEMORY, each SSL gets its own heap hint, and wolfSSL_free() releases it. Some objects allocated from that hint can live longer than the SSL: a session kept with wolfSSL_get1_session(), the server's peer cert stored in the session, or an X509 returned by wolfSSL_get_peer_certificate(). After wolfSSL_free(), these objects point at a hint that no longer exists.

  • Add refCount and sslOwned to WOLFSSL_HEAP_HINT, and the local helpers wc_HeapHint_Ref() and wc_HeapHint_Unref(). Only hints made by InitSSL_StaticMemory are counted.
  • InitSSL_StaticMemory starts the count at 1 for the SSL itself. FreeSSL_StaticMemory drops that reference instead of freeing the hint.
  • wolfSSL_NewSession and InitX509 (dynamic X509s) take a reference.
    wolfSSL_FreeSession and ExternalFreeX509 drop it after the final XFREE, since that free may release the hint.
  • Allocate the session from ssl->heap in InitSSL and wolfSSL_clear, and copy the peer leaf with wolfSSL_X509_dup() in
    PushPeerCertToChain.
  • wolfSSL_NewSession: free with the heap argument on the refcount mutex error path, not ret->heap, which isn't set yet.

Testing

  • test_wolfSSL_get1_session_static_heap and
    test_wolfSSL_session_ticket_static_heap: check that sessions use the
    per-SSL hint, and check its refCount as SSLs, sessions and session
    dups are freed, including across resumption.
  • test_wolfSSL_peer_cert_chain_static_heap: enable stats tracking, and
    take a curAlloc baseline after a first connection. Check refCount
    with the session as the last holder. Add a KEEP_PEER_CERT case where
    an X509 from wolfSSL_get_peer_certificate() is the last holder.
    Check that curAlloc returns to the baseline.
  • Add the helper test_peer_cert_static_heap_connect() for the repeated
    client-auth handshakes.
  • test_wolfSSL_CTX_add_session_ext: without WOLFSSL_TICKET_HAVE_ID, a
    TLS 1.2 ticket session has no session ID, so don't add it to the
    cache, and expect no remove callback on resumption.

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.

🟡 Changes recommended

The new regression tests need configuration fixes for builds without PEM parsing or TLS 1.2 client authentication.

2 open issues
What changed in this PR

This PR fixes session memory ownership so retained sessions do not depend on a connection’s freed static-memory heap hint.

Changes:

  • Create sessions using the context heap during initialization and reset.
  • Use the session heap for tickets, ticket nonces, and retained peer certificates.
  • Add regression tests for session retention, duplication, resumption, and cleanup.
File Description
tests/​api.c Adds static-memory session lifetime and cleanup tests.
src/​ssl.c Uses the context heap when wolfSSL_clear() replaces a session.
src/​ssl_api_cert.c Allocates peer-chain certificates from the session heap.
src/​internal.c Corrects session creation and ticket-related heap usage.

Review effort: Balanced

Comment thread tests/api.c Outdated
Comment thread tests/api.c Outdated

@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 #11899

Scan targets checked: wolfssl-src, wolfssl-bugs
Coverage: 2 of 4 in-scope changed file(s) opened by the reviewer; not opened: src/internal.c, tests/api.c

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

@aidankeefe2022
aidankeefe2022 marked this pull request as ready for review October 26, 2026 20:51
@github-actions

Copy link
Copy Markdown

retest this please

@danielinux danielinux changed the title Fenrir 15782 (HIGH): Allocate session memory from the CTX heap, not the SSL heap Fenrir 15782: Allocate session memory from the CTX heap, not the SSL heap Oct 27, 2026

@julek-wolfssl julek-wolfssl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is not a maintainable solution. Caller sites should not have knowledge about which hint to use. I would prefer to store a reference counter in WOLFSSL_HEAP_HINT and let the allocator figure out when it can be released. Attached is a detailed description of what I envision.

pr11899-heap-hint-refcount.md

With WOLFSSL_STATIC_MEMORY, each SSL gets its own heap hint, and
wolfSSL_free() releases it. Some objects allocated from that hint can
live longer than the SSL: a session kept with wolfSSL_get1_session(),
the server's peer cert stored in the session, or an X509 returned by
wolfSSL_get_peer_certificate(). After wolfSSL_free(), these objects
point at a hint that no longer exists.

Update the static heap session, ticket and peer cert chain tests to
check the hint's refCount as the SSL, sessions and X509s are freed.
Add a case where an X509 is the last holder. Check that curAlloc
returns to its baseline (except with WOLFSSL_STATIC_MEMORY_LEAN).

Fix test_wolfSSL_CTX_add_session_ext without WOLFSSL_TICKET_HAVE_ID:
a TLS 1.2 ticket session has no session ID, so it can't be added to
the cache, and the remove callback isn't called on resumption.
wc_Memory* inBuf;
byte haFlag; /* flag used for checking handshake count */
#endif
word32 refCount; /* SSL ref + other refs */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This needs to be wolfSSL_Ref and use the accompanying functions for using this type.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

fixed!

Comment thread src/x509.c
Comment on lines +4284 to 4293
#ifdef WOLFSSL_STATIC_MEMORY
void* heap = x509->heap;
#endif
FreeX509(x509);
XFREE(x509, x509->heap, DYNAMIC_TYPE_X509);
#ifdef WOLFSSL_STATIC_MEMORY
/* after the XFREE: it may free the hint x509 came from */
wc_HeapHint_Unref(heap);
#endif
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

My idea was that FreeSSL_StaticMemory would mark the heap as ready for release and then the last XFREE call would de-allocate the heap hint. This way wc_HeapHint_Unref doesn't need to be called by any caller and everything happens under the hood.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ohh yeah that is better! Fixing now

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.

4 participants