Skip to content

Fix OpenSSL transport handshake correctness and error-path leaks (#5486)#5681

Merged
pepone merged 3 commits into
zeroc-ice:mainfrom
pepone:fix/5486-openssl
Jun 24, 2026
Merged

Fix OpenSSL transport handshake correctness and error-path leaks (#5486)#5681
pepone merged 3 commits into
zeroc-ice:mainfrom
pepone:fix/5486-openssl

Conversation

@pepone

@pepone pepone commented Jun 23, 2026

Copy link
Copy Markdown
Member

Addresses #5486 (items 2, 3, 4, 6). One of a set of PRs splitting the grouped transport audit.

  • Add a default: to the handshake SSL_get_error switch so results such as SSL_ERROR_WANT_X509_LOOKUP/WANT_ASYNC (reachable with a user-supplied SSL_CTX) throw instead of busy-spinning.
  • Report the verify failure reason from X509_STORE_CTX_get_error(ctx) rather than the stale/generic SSL_get_verify_result(_ssl) inside the per-certificate verify callback.
  • Reject an empty IceSSL.CertFile before dereferencing &buffer[0] (undefined behavior on a zero-byte file).
  • Free leaked OpenSSL objects on error paths: the BIO when the context selection callback returns null, the popped extra-chain X509 when SSL_CTX_add_extra_chain_cert fails, and the X509 in decodeCertificate when X509_check_purpose fails.

The OpenSSL backend is not built on macOS; verified by review + codex (OpenSSL ownership semantics checked against the docs). CI exercises the Linux/OpenSSL build.

- Add a default case to the handshake SSL_get_error switch so results
  such as SSL_ERROR_WANT_X509_LOOKUP/WANT_ASYNC (reachable with a
  user-supplied SSL_CTX) throw instead of busy-spinning.
- Report the verify failure reason from X509_STORE_CTX_get_error(ctx)
  rather than the stale/generic SSL_get_verify_result(_ssl) inside the
  per-certificate verify callback.
- Reject an empty IceSSL.CertFile before dereferencing &buffer[0]
  (undefined behavior on a zero-byte file).
- Free leaked OpenSSL objects on error paths: the BIO when the context
  selection callback returns null, the popped extra-chain X509 when
  SSL_CTX_add_extra_chain_cert fails, and the X509 in decodeCertificate
  when X509_check_purpose fails.

Addresses zeroc-ice#5486 (items 2, 3, 4, 6).
Copilot AI review requested due to automatic review settings June 23, 2026 12:52
@pepone pepone added the cpp label Jun 23, 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.

Pull request overview

Note

Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.

Fixes several OpenSSL transport edge cases found in the transport audit: prevents handshake busy-spins on unhandled SSL_get_error results, improves verification failure reporting, and plugs a few error-path leaks/UB scenarios.

Changes:

  • Add a default case in the handshake error switch to throw on SSL_ERROR_WANT_* cases not driven by the event loop.
  • Improve certificate verification failure reporting by using X509_STORE_CTX_get_error(ctx) within the per-certificate callback.
  • Prevent UB on empty cert files and free OpenSSL objects correctly on several failure paths.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
cpp/src/Ice/SSL/SSLUtil.cpp Frees X509 on X509_check_purpose failure to avoid a leak.
cpp/src/Ice/SSL/OpenSSLTransceiverI.cpp Fixes error-path BIO leak, avoids handshake busy-spin, and improves verify error source.
cpp/src/Ice/SSL/OpenSSLEngine.cpp Rejects empty cert files before dereferencing buffer, and frees extra-chain cert on add failure.

Comment thread cpp/src/Ice/SSL/OpenSSLTransceiverI.cpp
Comment thread cpp/src/Ice/SSL/OpenSSLEngine.cpp
@pepone pepone requested a review from bernardnormier June 23, 2026 17:18
- In the handshake error switch, include the SSL_get_error code and the
  handshake return value in the default-case message. That case catches
  SSL_ERROR_WANT_* results for which the OpenSSL error queue is typically
  empty, so sslErrors() alone reports no actionable reason.
- Report the resolved certificate path (the file actually read) in the
  empty-certificate message instead of the configured certFile value.

@bernardnormier bernardnormier 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.

Verified each fix against OpenSSL ownership semantics (popped c so no double-free, X509_STORE_CTX_get_error is the right in-callback reason source, local x leak). All correct. Changelog scoping looks right.

@pepone pepone merged commit b6c60d0 into zeroc-ice:main Jun 24, 2026
47 checks passed
pepone added a commit that referenced this pull request Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants