Skip to content

Clear a NULL cert_cb back to the empty variant (fixes #537) - #538

Closed
dorianverlaine wants to merge 1 commit into
cloudflare:masterfrom
dorianverlaine:cert-cb-clear
Closed

dorianverlaine wants to merge 1 commit into
cloudflare:masterfrom
dorianverlaine:cert-cb-clear

Conversation

@dorianverlaine

Copy link
Copy Markdown

Fixes #537.

This carries the BoringSSL fix as a boring-sys/patches/ entry so 5.3.x users have an escape hatch while the change makes its way into BoringSSL, and adds a regression test that reproduces the crash on unpatched 5.3.0.

The change

  • boring-sys/patches/cert-cb-clear.patch resets cert_cb.cb to std::monostate when NULL is passed to ssl_cert_set_cert_cb (both overloads), restoring the previous "NULL clears" behavior.
  • boring-sys/build/main.rs applies the patch unconditionally, next to the post-quantum patch.
  • boring/src/ssl/test/cert_cb_clear.rs arms a blocking certificate callback and clears it right before the handshake — the same sequence a resumable accept uses to unblock a paused handshake.

Verification

  • On macOS aarch64 (macOS 27.0.1): without the patch, the new test aborts with SIGSEGV: invalid memory reference; with the patch, the handshake completes and the full boring lib suite passes (300 passed, 0 failed, 1 ignored).
  • cargo fmt --all -- --check and cargo clippy --all --all-targets --features rpk,prf,mlkem,mldsa are clean locally.
  • The original end-to-end repro (a pingora-based server clearing the callback across resumed handshakes) goes from 33 failing TLS integration tests to fully green with this change.

Happy to rework if you would rather land the fix upstream first and pick it up with the next revision bump.

The BoringSSL revision in 5.3.0 (427ec40c) stores a null cert_cb as an
`OldCallback` alternative instead of resetting the variant to `monostate`,
so `CertCb::operator bool()` reports a cleared callback as present and
`do_cert_callback` invokes a null function pointer (cloudflare#537).
That breaks the established "set NULL to clear" behavior that the
resumable accept in pingora relies on and crashes any handshake that
resumes after the callback was cleared.

Carry the upstream fix as a `boring-sys/patches/` entry so 5.3.x users
are not blocked while it makes its way into BoringSSL, and add a
regression test that arms and then clears the callback before a
handshake; without the patch the test process dies with SIGSEGV, with it
the handshake completes.
@dorianverlaine

dorianverlaine commented Oct 17, 2026 •

Copy link
Copy Markdown
Author

Withdrawing this report and the accompanying patch. We can reproduce the behavior consistently, but from the available documentation and upstream discussion we cannot determine whether the NULL assignment in 5.3.0 is intentional contract behavior or eventually an unsupported use of SSL_set_cert_cb on our side. We are not asserting that the behavior is correct—only that we cannot classify it with enough confidence to keep it open as an upstream defect. The reproduction and proposed test remain above for reference.

@dorianverlaine
dorianverlaine deleted the cert-cb-clear branch October 17, 2026 19:03
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.3.0 regression: SSL_set_cert_cb(..., NULL, ...) stores a null function pointer instead of clearing, crashing the next handshake

1 participant