fix: ~ecdsa_preprocessing_data cleanses over live std::map/std::vector members (UB + leak)#57
Open
grecow wants to merge 1 commit into
Open
Conversation
OPENSSL_cleanse(k.data, sizeof(ecdsa_preprocessing_data)) passes the size of the WHOLE struct. Because k is the first member, k.data aliases the object base, so the cleanse spans the non-trivial members mta_request (std::vector), G_proofs and public_data (std::map). A user-declared destructor body runs before the implicit member destructors, so this zeroes the live container control blocks; the subsequent ~vector/~map then operate on zeroed internals (undefined behaviour + heap leak of their allocations). Cleanse each secret scalar individually instead, leaving the containers to their own destructors. Mirrors the correct pattern already used by eddsa_signature_data in eddsa_online_signing_service.h (sizeof(k.data)). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
ecdsa_preprocessing_data(ininclude/cosigner/cmp_ecdsa_signing_service.h) has:kis the first member, sok.dataaliases the object base — but the size passed issizeof(ecdsa_preprocessing_data), i.e. the entire struct. That span covers the threenon-trivially-destructible members:
A user-declared destructor body runs before the implicit member destructors, so the
OPENSSL_cleansezeroes the live control blocks of the vector and the two maps(begin/end/root pointers, node counts). The subsequent
~vector/~mapthen run on thosezeroed internals — undefined behaviour, and in practice a heap leak of every map node
and vector buffer (these are populated per-signing from peer messages).
Fix
Cleanse each secret scalar individually and let the containers destruct normally. This mirrors
the correct pattern already used by the EdDSA analog
eddsa_signature_data(
include/cosigner/eddsa_online_signing_service.h), which cleansessizeof(k.data)rather thanthe whole struct.
Notes
k, gamma, a, b, delta, chiare still wiped); only the erroneous over-write of the live container internals is removed.
within the object; no OOB).
-fsanitize=addressand runecdsa_online_test/ecdsa_offline_test; LeakSanitizer flags the orphaned allocations before this change and isclean after.