Skip to content

session: initialize the external cache copy flag to 1 - #11460

Open
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_14055
Open

yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_14055

Conversation

@yosuke-wolfssl

@yosuke-wolfssl yosuke-wolfssl commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Problem

get_sess_cb receives an int *copy saying who owns the session it returns.
wolfSSL initialized it to 0 — "the cache handed us its reference" — while
OpenSSL initializes it to 1 and calls SSL_SESSION_up_ref(). A conforming
callback that never writes *copy therefore had wolfSSL_FreeSession() called
on its cached session. The count starts at 1, so the session was ForceZeroed
and freed while the application cache still pointed at it, and each further
resumption from a peer holding that session ID dereferenced freed memory.

Two related defects on the same flag: TlsSessionIdIsValid() read copy
uninitialized, and no call site took a reference for the span it used the
session, so a concurrent eviction could free it mid-handshake.

Fix (src/ssl_sess.c)

Three call sites read the flag — wolfSSL_GetSessionFromCache(),
GetSesionFromCacheOrExt() (src/internal.c) and TlsSessionIdIsValid()
(src/dtls.c). Each now initializes it to 1 and releases one reference on
every path:

  • copy left setwolfSSL_SESSION_up_ref() pins the session for the
    lookup. Net zero; the cache keeps ownership.
  • copy cleared — the callback's reference transfers to wolfSSL, which
    releases it. Unchanged behavior.
  • up_ref fails (a non-WOLFSSL_SESSION_TYPE_HEAP session) — treated as a
    lookup miss, nothing freed.

wolfSSL_CTX_sess_set_get_cb() gains its first doxygen entry, English and
Japanese, now the single statement of this contract.

Closes f-14055.

Porting note: the default flips. A get_sess_cb that returned a freshly
allocated session and relied on wolfSSL to free it will now leak, and should
set *copy = 0 explicitly. Such a callback already leaks against OpenSSL.

Tests

test_wolfSSL_CTX_sess_get_cb_default_copy() resumes TLS 1.2 through a
callback returning a cached session, holding a second reference so a dropped
one is observable without a use-after-free:

  • copy left alone — reference count unchanged.
  • copy cleared — wolfSSL takes exactly one reference.

No prior test returned a non-NULL session with copy at its default.

Verification

  • Clean build; unit.test --api 1587 passed, 0 failed; make check 12 passed,
    0 failed; ASan + UBSan clean across the API suite.
  • Instrumented the hold window: with copy set the count goes 2 -> 3 and back
    to 2; with copy cleared it stays 2, then drops to 1.
  • Negative controls: restoring the old default fails the unchanged-count
    assertion; removing the copy = 0 release fails the other.

Not in this PR

No test asserts reference counts across a resume on the TLS 1.3
stateful-ticket or DTLS paths. Instrumenting all three sites over the API suite
shows GetSesionFromCacheOrExt reached only with copy already overwritten to
1, and TlsSessionIdIsValid's external-cache block not reached at all — both
predate this change. The up_ref-failure branch needs fault injection.

@yosuke-wolfssl yosuke-wolfssl self-assigned this Sep 15, 2026
Copilot AI lite review requested due to automatic review settings September 15, 2026 06:44

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.

🔵 Needs a closer look

Add coverage for both ownership modes in the TLS 1.3 and DTLS cache paths.

Pull request overview

Aligns external session-cache ownership with OpenSSL by defaulting copy to 1, with regression coverage and documentation updates.

Changes:

  • Updates TLS, TLS 1.3, and DTLS cache ownership defaults.
  • Adds TLS 1.2 ownership and reference-count tests.
  • Documents callback ownership semantics in English and Japanese.
File summaries
File Summary
tests/api/test_session.h Registers the session-cache ownership test.
tests/api/test_session.c Adds ownership and reference-count regression coverage.
src/ssl_sess.c Fixes the standard TLS cache ownership default.
src/internal.c Fixes the TLS 1.3 stateful-ticket ownership default.
src/dtls.c Initializes the DTLS cache ownership flag.
doc/dox_comments/header_files/ssl.h Documents callback ownership semantics.
doc/dox_comments/header_files-ja/ssl.h Adds the Japanese documentation mirror.
Review details

Suppressed comments (2)

src/dtls.c:470

  • This is the DTLS session-ID lookup ownership path, but the new regression test covers only TLS 1.2 stream resumption. Without a DTLS test that returns a cached session with copy untouched and then cleared, this changed lifetime behavior can regress undetected; please add coverage for both ownership modes.
    int copy = 1;

src/internal.c:43666

  • This initializes the ownership default for the TLS 1.3 stateful-ticket lookup, but the added regression test only drives the TLS 1.2 wolfSSL_GetSessionFromCache() path. A future regression here could still free a cached session or leak a transferred one without detection; please add a stateful-ticket test that exercises both the untouched and cleared copy cases.
  • Files reviewed: 7/7 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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

Scan targets checked: wolfssl-src, wolfssl-bugs

Findings: 3
3 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

Comment thread src/internal.c
Comment thread src/dtls.c
Comment thread tests/api/test_session.c
- wolfSSL_GetSessionFromCache(), GetSesionFromCacheOrExt() and
  TlsSessionIdIsValid() initialize to 1 the copy flag passed to
  ctx->get_sess_cb(), take a reference with
  wolfSSL_SESSION_up_ref() when the callback leaves it set, and
  release one with wolfSSL_FreeSession() on every path. A session
  they cannot reference is treated as a lookup miss.
  GetSesionFromCacheOrExt() sets freeCtx->extCache and
  freeCtx->freeSess together.
- Comments restating the copy flag's contract are removed, or
  replaced with ones naming the reference held.
- ssl.h dox comments, English and Japanese, document
  wolfSSL_CTX_sess_set_get_cb() and both values of its copy flag.
- tests/api/test_session.c and test_session.h add
  test_wolfSSL_CTX_sess_get_cb_default_copy(): a TLS 1.2 resume
  with copy left alone checks the reference count is unchanged, a
  second with copy cleared checks wolfSSL takes exactly one.

Issue: F-14055
Comment thread src/internal.c
Comment thread src/dtls.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 #11460

Scan targets checked: wolfssl-src, wolfssl-bugs

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

💬 1 finding(s) from an earlier review are still open and were not re-posted:

  • Default-copy test accepts missing reference acquisition — tests/api/test_session.c:1075

This review was generated automatically by Fenrir. Reported findings require changes before merge.

Comment thread tests/api/test_session.c
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