Skip to content

Fix BIGNUM leak in _new_key_from_parameters on pre-3.x#195

Draft
toddr-bot wants to merge 1 commit into
cpan-authors:mainfrom
toddr-bot:koan.toddr.bot/fix-keygen-param-leak
Draft

Fix BIGNUM leak in _new_key_from_parameters on pre-3.x#195
toddr-bot wants to merge 1 commit into
cpan-authors:mainfrom
toddr-bot:koan.toddr.bot/fix-keygen-param-leak

Conversation

@toddr-bot
Copy link
Copy Markdown
Contributor

Summary

  • On pre-3.x OpenSSL, _new_key_from_parameters could leak or double-free BIGNUMs when an error occurred between ownership transfer (RSA_set0_key/RSA_set0_factors/direct struct assign) and the NULLing of those pointers
  • Adds an xfer bitmask (bit 0=n+e, bit 1=p+q, bit 2=d) that tracks which BIGNUM groups have been transferred to the RSA struct
  • The err handler now conditionally frees only un-transferred BIGNUMs on pre-3.x; 3.0+ path unchanged (OSSL_PARAM_BLD copies values, so caller always owns originals)

Test plan

  • Full test suite passes (667 tests)
  • Valgrind on pre-3.x builds (CI covers bookworm/3.0 with Valgrind; this fix targets older OpenSSL)
  • CI matrix: bullseye (1.1.1), bookworm (3.0.x), trixie (3.4.x), AlmaLinux 9, macOS LibreSSL

🤖 Generated with Claude Code

On OpenSSL < 3.0, RSA_set0_key/RSA_set0_factors transfer ownership of
BIGNUM pointers to the RSA struct.  If a subsequent THROW fired between
ownership transfer and the NULLing of those pointers, the err handler
would unconditionally call BN_clear_free on already-transferred BIGNUMs,
causing a double-free (RSA_free also frees them).

Conversely, if THROW fired *before* ownership transfer, the err handler
on pre-3.x had no code to free the pointer_copy'd BIGNUMs at all,
leaking them.

Fix both issues with an `xfer` bitmask that tracks which groups of
BIGNUMs have been transferred to the RSA struct:
  bit 0 = n, e
  bit 1 = p, q
  bit 2 = d

The err handler now conditionally frees only un-transferred BIGNUMs
on pre-3.x.  On 3.0+, OSSL_PARAM_BLD_push_BN copies values so the
caller always owns the originals and the existing unconditional free
is correct.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

1 participant