Guard against sizes that do not fit in an int
What changed, and why it matters
This commit adds a safety check in the Ledger Bitcoin app's code that handles BIP32 derivation paths extracted from a PSBT (Partially Signed Bitcoin Transaction). The change prevents a very large, attacker-chosen data length from being silently truncated when converted from a large unsigned integer (size_t) to a signed integer (int). Such truncation could theoretically cause the app to allocate or read/write the wrong amount of memory, potentially leading to crashes or memory corruption. The patch is narrow and defensive, but it does not show a complete exploit path.
Review the full call chain to ensure cs->result = -1 is properly propagated and causes the signing operation to abort safely. Consider adding unit tests with oversized PSBT fields and verify no other size_t-to-int conversions exist in the PSBT handler code.
Security signals we found
Integer truncation / signedness issue between size_t and int
Memory safety hardening in PSBT parsing path
Defensive bounds check added in callback
Potential denial-of-service or memory corruption vector in BIP32 derivation extraction
Evidence from the diff
In src/handler/sign_psbt/extract_bip32_derivation.c, the fpt_der_data_len_callback receives a size_t data_length and previously assigned it directly to an int field (total_data_length) in the callback state. On platforms where size_t is wider than int, a maliciously large data_length would be truncated. The patch guards against this by checking if data_length exceeds INT_MAX, setting cs->result = -1 and returning early. This is a partial hardening measure; the commit does not show how the result field is consumed downstream or whether callers actually abort on error.
Changed components
src/handler/sign_psbt/extract_bip32_derivation.cLedger Bitcoin app PSBT signing flowBIP32 derivation path extractionInspect captured patch +10 / −1
diff --git a/src/handler/sign_psbt/extract_bip32_derivation.c b/src/handler/sign_psbt/extract_bip32_derivation.c
index 1cd5d9a..2976464 100644
--- a/src/handler/sign_psbt/extract_bip32_derivation.c
+++ b/src/handler/sign_psbt/extract_bip32_derivation.c
@@ -1,5 +1,6 @@
#include <stdint.h>
#include <string.h>
+#include <limits.h>
#include "extract_bip32_derivation.h"
@@ -21,7 +22,15 @@ typedef struct {
} fpt_der_callback_data_t;
static void fpt_der_data_len_callback(size_t data_length, void *callback_state) {
- ((fpt_der_callback_data_t *) callback_state)->total_data_length = data_length;
+ fpt_der_callback_data_t *cs = (fpt_der_callback_data_t *) callback_state;
+
+ if (data_length > INT_MAX) {
+ // fail early if the conversion to int would overflow
+ // by setting the error result in the callback state
+ cs->result = -1;
+ return;
+ }
+ cs->total_data_length = data_length;
}
static void fpt_der_data_callback(buffer_t *data, void *callback_state) {
Why this scored 58/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.