build: fix clear sizes and index type
What changed, and why it matters
This commit fixes two small but meaningful memory-handling bugs in a Bitcoin/Elements cryptographic library. One fix changes a memory-clearing call so it actually wipes the intended structure instead of just a pointer variable. The other changes an index variable from a signed to an unsigned type, preventing a subtle type-related bug when handling special transaction issuance flags. The commit message does not describe these as security fixes, but the memory-clearing fix in particular is the kind of issue that can leave secret key material or sensitive data in memory longer than intended.
Treat as a low-to-moderate security hardening patch. Users building from source should update to a revision containing this commit. Downstream projects should backport if they rely on the affected signing and PSBT functions and have strict memory-clearing requirements. No emergency response is indicated because the commit message does not frame this as an exploitable vulnerability and the exposure window is narrow (error path and short-lived stack variables).
Security signals we found
Sensitive memory not fully cleared due to sizeof(pointer) bug in error path (PSBT initialization failure)
Private key material (secp256k1_keypair) not fully cleared after Schnorr signing due to sizeof(pointer) bug
Signed/unsigned type mismatch for transaction input index with issuance flag manipulation
Evidence from the diff
In src/psbt.c, wally_clear(psbt_out, sizeof(psbt_out)) is corrected to wally_clear(psbt_out, sizeof(*psbt_out)). The original code clears only the size of a pointer (typically 8 bytes on 64-bit systems), not the full wally_psbt structure, so sensitive fields could remain uncleared on the error path. In src/sign.c, wally_clear(&keypair, sizeof(&keypair)) is corrected to wally_clear(&keypair, sizeof(keypair)). The original clears only the size of a pointer to keypair, not the 96-byte secp256k1_keypair object, leaving private key material in stack memory after Schnorr signing. Also in src/psbt.c, src_index is changed from int to uint32_t to match src->index and avoid signed/unsigned issues when OR-ing with WALLY_TX_ISSUANCE_FLAG.
Changed components
src/psbt.c: psbt_init() error cleanupsrc/psbt.c: psbt_build_input() issuance flag handlingsrc/sign.c: wally_ec_sig_from_bytes_aux() Schnorr signing pathInspect captured patch +3 / −3
diff --git a/src/psbt.c b/src/psbt.c
index d098000..5f47472 100644
--- a/src/psbt.c
+++ b/src/psbt.c
@@ -1196,7 +1196,7 @@ static int psbt_init(uint32_t version, size_t num_inputs, size_t num_outputs,
wally_free(psbt_out->inputs);
wally_free(psbt_out->outputs);
wally_map_clear(&psbt_out->unknowns);
- wally_clear(psbt_out, sizeof(psbt_out));
+ wally_clear(psbt_out, sizeof(*psbt_out));
return ret != WALLY_OK ? ret : WALLY_ENOMEM;
}
@@ -3961,7 +3961,7 @@ static int psbt_build_input(const struct wally_psbt_input *src,
BUILD_ITEM(inflation_keys_rangeproof, PSET_IN_ISSUANCE_INFLATION_KEYS_RANGEPROOF);
struct wally_map_item issuance_amount_item = { NULL, 0, issuance_amount, sizeof(issuance_amount) };
struct wally_map_item inflation_keys_item = { NULL, 0, inflation_keys, sizeof(inflation_keys) };
- int src_index = src->index;
+ uint32_t src_index = src->index;
if (src->issuance_amount || src->inflation_keys || issuance_amount_commitment || inflation_keys_commitment)
src_index |= WALLY_TX_ISSUANCE_FLAG;
diff --git a/src/sign.c b/src/sign.c
index e94547a..e803b09 100644
--- a/src/sign.c
+++ b/src/sign.c
@@ -359,7 +359,7 @@ int wally_ec_sig_from_bytes_aux(const unsigned char *priv_key, size_t priv_key_l
ret = WALLY_EINVAL;
else if (!secp256k1_schnorrsig_sign32(ctx, bytes_out, bytes, &keypair, aux_rand))
ret = WALLY_ERROR;
- wally_clear(&keypair, sizeof(&keypair));
+ wally_clear(&keypair, sizeof(keypair));
return ret;
} else {
unsigned char extra_entropy[32] = {0}, *entropy_p = (unsigned char *)aux_rand;
Why this scored 35/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.