What changed, and why it matters
This commit fixes a logic bug in the Ledger Bitcoin app's Miniscript policy analyzer. The code that decides whether a Bitcoin spending policy is 'm' (a technical property used during transaction signing) was checking the wrong counter. It now also requires that all sub-policies satisfy the 'm' property, not just the 'e' property. This could have caused the device to incorrectly approve or classify a Bitcoin transaction policy, potentially leading to wrong security assumptions during wallet operations.
Review related Miniscript property computations in the same function for analogous missing counter checks; add regression tests for 'm' flag computation on threshold policies; verify whether any released firmware versions shipped with this bug and assess whether it could affect transaction signing safety.
Security signals we found
Incorrect boolean logic in security-critical policy analysis
Missing validation of 'm' property for threshold Miniscript fragments
Miniscript correctness bug in hardware wallet firmware
Potential for wrong transaction policy classification
Evidence from the diff
In compute_miniscript_policy_ext_info(), the ‘thresh’ policy node handler computes Miniscript property flags (s, e, m, x) for threshold-k-of-n policies. The original code set out->m based on count_e == node->n and count_not_s <= node->k, but failed to verify count_m == node->n. The patch adds the missing count_m == node->n conjunct. This is a correctness fix in the static policy analysis that determines whether a fragment is ‘m’ (non-zero probability of being satisfied without signing; related to non-malleability/witness correctness). A wrong ‘m’ value could lead to incorrect policy eligibility or signing behavior for Miniscript wallets.
Changed components
src/common/wallet.ccompute_miniscript_policy_ext_info()Miniscript 'thresh' policy node handlingInspect captured patch +1 / −1
diff --git a/src/common/wallet.c b/src/common/wallet.c
index a16a535..9b29e5f 100644
--- a/src/common/wallet.c
+++ b/src/common/wallet.c
@@ -2666,7 +2666,7 @@ int compute_miniscript_policy_ext_info(const policy_node_t *policy_node,
out->s = count_not_s <= node->k - 1 ? 1 : 0;
out->e = count_s == node->n ? 1 : 0;
- out->m = (count_e == node->n && count_not_s <= node->k) ? 1 : 0;
+ out->m = (count_e == node->n && count_m == node->n && count_not_s <= node->k) ? 1 : 0;
out->x = 0;
Why this scored 59/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.