Skip to content

crypto/evp: fix double free of tmp_keymgmt in evp_keyexch_init() - #31394

Closed
sucloudflare wants to merge 1 commit into
openssl:masterfrom
sucloudflare:fix/exchange-clean
Closed

sucloudflare wants to merge 1 commit into
openssl:masterfrom
sucloudflare:fix/exchange-clean

Conversation

@sucloudflare

Copy link
Copy Markdown
Contributor

Commit a21f77d fixed the double free of
tmp_keymgmt in the provider fallback loop for kem, signature and
asymcipher, but the identical pattern in evp_keyexch_init()
(crypto/evp/exchange.c) was missed.

At the top of the retry loop, EVP_KEYEXCH_free(exchange) and
EVP_KEYMGMT_free(tmp_keymgmt) are called before each attempt. When
evp_pkey_export_to_provider() sets tmp_keymgmt to NULL, the guard frees
tmp_keymgmt_tofree (PTR_B) but does not NULL out tmp_keymgmt. On the
next iteration, EVP_KEYMGMT_free(tmp_keymgmt) is called again on the
already-freed PTR_B — a double free.

Fix: add exchange = NULL and tmp_keymgmt = NULL after each free at the
top of the loop, consistent with the fix applied by a21f77d to kem.c,
asymcipher.c and signature.c.

Fixes: a21f77d ("crypto/evp: fix double free of tmp_keymgmt in sig/kem/asym init")

cc @nhorman @t8m

@nhorman
nhorman requested a review from t8m June 4, 2026 23:38
@andrewkdinh
andrewkdinh self-requested a review June 5, 2026 03:45
@t8m t8m added branch: master Applies to master branch triaged: bug The issue/pr is/fixes a bug tests: exempted The PR is exempt from requirements for testing branch: 3.4 Applies to openssl-3.4 branch: 3.5 Applies to openssl-3.5 branch: 3.6 Applies to openssl-3.6 branch: 4.0 Applies to openssl-4.0 labels Jun 5, 2026
@openssl-machine openssl-machine added approval: done This pull request has the required number of approvals and removed approval: review pending This pull request needs review by a committer labels Jun 5, 2026
@t8m t8m closed this Jun 5, 2026
@t8m t8m reopened this Jun 5, 2026
@github-actions github-actions Bot added the severity: fips change The pull request changes FIPS provider sources label Jun 5, 2026
@esyr

esyr commented Jun 5, 2026

Copy link
Copy Markdown
Member

There is no double-free, the description is bogus:

evp_pkey_export_to_provider() sets tmp_keymgmt to NULL

Yes, that's true.

the guard frees tmp_keymgmt_tofree (PTR_B)

Yes.

but does not NULL out tmp_keymgmt

It does not need to, tmp_keymgmt is NULL already, as noted before.

On the next iteration, EVP_KEYMGMT_free(tmp_keymgmt) is called again on the already-freed PTR_B — a double free.

No, because tmp_keymgmt is NULL, as you've noticed before?

@esyr esyr added the hold: discussion The community needs to establish a consensus how to move forward with the issue or PR label Jun 5, 2026
@sucloudflare

Copy link
Copy Markdown
Contributor Author

Thank you for the detailed review, @esyr. You're correct that within the retry loop, evp_pkey_export_to_provider() sets *tmp_keymgmt to NULL via the pointer argument when it doesn't consume the keymgmt, making the subsequent EVP_KEYMGMT_free(tmp_keymgmt) at the top of the next iteration a safe no-op. The description overstated the issue as a confirmed double-free.
That said, the inconsistency this patch addresses is real: kem.c, asymcipher.c, and signature.c — all touched by a21f77d — explicitly null out tmp_keymgmt after freeing it at the err:, legacy:, and success exit paths. The pre-patch exchange.c lacked these same null assignments at those same exit points, making it the only outlier in the family.
The fix is therefore less about preventing an active double-free and more about bringing exchange.c into consistency with the established pattern in its sibling files — which matters for code clarity and safety under future refactors. Happy to update the commit message to reflect this more accurately if that helps move the patch forward.

@openssl-machine openssl-machine added the hold: cla required The contributor needs to submit a license agreement. label Jun 5, 2026
@sucloudflare

Copy link
Copy Markdown
Contributor Author

Commit message has been updated to remove the double-free claim. The patch now accurately describes its intent as a consistency fix with the sibling files. Happy to address any remaining concerns.

@openssl-machine

Copy link
Copy Markdown
Collaborator

24 hours has passed since 'approval: done' was set, but as this PR has been updated in that time the label 'approval: ready to merge' is not being automatically set. Please review the updates and set the label manually.

@sucloudflare

Copy link
Copy Markdown
Contributor Author

CLA has been signed under [email protected]. The automated check does not seem to reflect this. Could @t8m or @nhorman verify manually?

@nhorman

nhorman commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

I can't check at the moment, but i can say that this usually happens after a cla is signed because the commit.in the pr contains an author email that doesn't match the one you signed your cla for. Please check that and, if need be, got commit --amend --reset-author your change specifying the proper email then force.push the changes.

Commit a21f77d added explicit null assignments after EVP_KEYMGMT_free()
calls at the err:, legacy:, and success exit paths in kem.c,
asymcipher.c and signature.c.

The identical exit paths in evp_keyexch_init() (crypto/evp/exchange.c)
were not updated at the same time, leaving exchange.c as the only
outlier in the family without these null assignments.

This patch brings exchange.c into consistency with its sibling files
by adding exchange = NULL and tmp_keymgmt = NULL after each free at
the exit paths, matching the established pattern from a21f77d.

No functional change intended.
@openssl-machine openssl-machine removed the hold: cla required The contributor needs to submit a license agreement. label Jun 6, 2026
@sucloudflare

Copy link
Copy Markdown
Contributor Author

CLA is now resolved. The patch intent has been updated to reflect a consistency fix rather than a double-free. Happy to address any remaining concerns from @esyr before this moves forward.

@t8m t8m added triaged: cleanup The issue/pr deals with cleanup of comments/docs not altering code significantly approval: ready to merge The 24 hour grace period has passed, ready to merge and removed hold: discussion The community needs to establish a consensus how to move forward with the issue or PR approval: done This pull request has the required number of approvals labels Jun 8, 2026
@t8m

t8m commented Jun 8, 2026

Copy link
Copy Markdown
Member

IMO it can be merged with the updated commit message after the release.

openssl-machine pushed a commit that referenced this pull request Jun 10, 2026
Commit a21f77d added explicit null assignments after EVP_KEYMGMT_free()
calls at the err:, legacy:, and success exit paths in kem.c,
asymcipher.c and signature.c.

The identical exit paths in evp_keyexch_init() (crypto/evp/exchange.c)
were not updated at the same time, leaving exchange.c as the only
outlier in the family without these null assignments.

This patch brings exchange.c into consistency with its sibling files
by adding exchange = NULL and tmp_keymgmt = NULL after each free at
the exit paths, matching the established pattern from a21f77d.

No functional change intended.

Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
MergeDate: Wed Jun 10 11:20:19 2026
(Merged from #31394)
@jogme

jogme commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Merged to the labeled branches. Thank you for your contribution!

@jogme jogme closed this Jun 10, 2026
openssl-machine pushed a commit that referenced this pull request Jun 10, 2026
Commit a21f77d added explicit null assignments after EVP_KEYMGMT_free()
calls at the err:, legacy:, and success exit paths in kem.c,
asymcipher.c and signature.c.

The identical exit paths in evp_keyexch_init() (crypto/evp/exchange.c)
were not updated at the same time, leaving exchange.c as the only
outlier in the family without these null assignments.

This patch brings exchange.c into consistency with its sibling files
by adding exchange = NULL and tmp_keymgmt = NULL after each free at
the exit paths, matching the established pattern from a21f77d.

No functional change intended.

Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
MergeDate: Wed Jun 10 11:21:39 2026
(Merged from #31394)
openssl-machine pushed a commit that referenced this pull request Jun 10, 2026
Commit a21f77d added explicit null assignments after EVP_KEYMGMT_free()
calls at the err:, legacy:, and success exit paths in kem.c,
asymcipher.c and signature.c.

The identical exit paths in evp_keyexch_init() (crypto/evp/exchange.c)
were not updated at the same time, leaving exchange.c as the only
outlier in the family without these null assignments.

This patch brings exchange.c into consistency with its sibling files
by adding exchange = NULL and tmp_keymgmt = NULL after each free at
the exit paths, matching the established pattern from a21f77d.

No functional change intended.

Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
MergeDate: Wed Jun 10 11:21:26 2026
(Merged from #31394)
openssl-machine pushed a commit that referenced this pull request Jun 10, 2026
Commit a21f77d added explicit null assignments after EVP_KEYMGMT_free()
calls at the err:, legacy:, and success exit paths in kem.c,
asymcipher.c and signature.c.

The identical exit paths in evp_keyexch_init() (crypto/evp/exchange.c)
were not updated at the same time, leaving exchange.c as the only
outlier in the family without these null assignments.

This patch brings exchange.c into consistency with its sibling files
by adding exchange = NULL and tmp_keymgmt = NULL after each free at
the exit paths, matching the established pattern from a21f77d.

No functional change intended.

Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
MergeDate: Wed Jun 10 11:21:08 2026
(Merged from #31394)
openssl-machine pushed a commit that referenced this pull request Jun 10, 2026
Commit a21f77d added explicit null assignments after EVP_KEYMGMT_free()
calls at the err:, legacy:, and success exit paths in kem.c,
asymcipher.c and signature.c.

The identical exit paths in evp_keyexch_init() (crypto/evp/exchange.c)
were not updated at the same time, leaving exchange.c as the only
outlier in the family without these null assignments.

This patch brings exchange.c into consistency with its sibling files
by adding exchange = NULL and tmp_keymgmt = NULL after each free at
the exit paths, matching the established pattern from a21f77d.

No functional change intended.

Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
MergeDate: Wed Jun 10 11:21:50 2026
(Merged from #31394)
n13l pushed a commit to n13l/openssl that referenced this pull request Jul 25, 2026
Commit a21f77d added explicit null assignments after EVP_KEYMGMT_free()
calls at the err:, legacy:, and success exit paths in kem.c,
asymcipher.c and signature.c.

The identical exit paths in evp_keyexch_init() (crypto/evp/exchange.c)
were not updated at the same time, leaving exchange.c as the only
outlier in the family without these null assignments.

This patch brings exchange.c into consistency with its sibling files
by adding exchange = NULL and tmp_keymgmt = NULL after each free at
the exit paths, matching the established pattern from a21f77d.

No functional change intended.

Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
MergeDate: Wed Jun 10 11:20:19 2026
(Merged from openssl#31394)
rickyringler pushed a commit to rickyringler/openssl that referenced this pull request Aug 21, 2026
Commit a21f77d added explicit null assignments after EVP_KEYMGMT_free()
calls at the err:, legacy:, and success exit paths in kem.c,
asymcipher.c and signature.c.

The identical exit paths in evp_keyexch_init() (crypto/evp/exchange.c)
were not updated at the same time, leaving exchange.c as the only
outlier in the family without these null assignments.

This patch brings exchange.c into consistency with its sibling files
by adding exchange = NULL and tmp_keymgmt = NULL after each free at
the exit paths, matching the established pattern from a21f77d.

No functional change intended.

Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
MergeDate: Wed Jun 10 11:20:19 2026
(Merged from openssl#31394)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval: ready to merge The 24 hour grace period has passed, ready to merge branch: master Applies to master branch branch: 3.4 Applies to openssl-3.4 branch: 3.5 Applies to openssl-3.5 branch: 3.6 Applies to openssl-3.6 branch: 4.0 Applies to openssl-4.0 severity: fips change The pull request changes FIPS provider sources tests: exempted The PR is exempt from requirements for testing triaged: bug The issue/pr is/fixes a bug triaged: cleanup The issue/pr deals with cleanup of comments/docs not altering code significantly

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants