sign_psbt: disable pset parsing on non-psram devices
What changed, and why it matters
This commit blocks PSET (a privacy-enhanced Bitcoin transaction format) parsing on Blockstream Jade hardware wallets that lack extra RAM (SPIRAM). The change prevents the device from running out of memory while handling complex PSET data. It is a hardening/defensive fix rather than a clear exploit patch, because the commit message and diff do not describe an actual vulnerability—only a known resource limitation.
Treat as a defensive resource-limitation fix. For non-SPIRAM Jade users, confirm that PSET signing is now rejected gracefully and that callers surface the error message. Complete the TODO to return a clear user-facing error. If a security advisory is warranted, it should be limited to a low-severity denial-of-service scenario on affected hardware.
Security signals we found
Denial-of-service hardening: prevents memory exhaustion on constrained devices
PSET parsing disabled on non-SPIRAM variants
Explicit TODO noting callers should return a user-facing error message
No explicit vulnerability, CVE, or exploit described in commit materials
Evidence from the diff
In main/process/sign_psbt.c, deserialise_psbt() now checks CONFIG_SPIRAM before parsing a PSET. On devices without SPIRAM it logs an error and returns false, instead of spawning a 54 KB temporary task via run_in_temporary_task(). The comment says non-SPIRAM devices lack sufficient free memory to parse/process any reasonable PSET. The patch therefore disables a feature on low-memory hardware to avoid potential memory exhaustion or instability.
Changed components
main/process/sign_psbt.cPSET transaction parsing pathBlockstream Jade devices without SPIRAMInspect captured patch +8 / −0
diff --git a/main/process/sign_psbt.c b/main/process/sign_psbt.c
index f083d1d..607dd64 100644
--- a/main/process/sign_psbt.c
+++ b/main/process/sign_psbt.c
@@ -1076,9 +1076,17 @@ bool deserialise_psbt(const uint8_t* bytes, const size_t bytes_len, struct wally
// PSBT - can parse immediately
ret = parse_psbt_bytes(&data);
} else if (!memcmp(bytes, PSET_MAGIC_PREFIX, sizeof(PSET_MAGIC_PREFIX))) {
+#ifdef CONFIG_SPIRAM
// PSET - can need large stack to unblind and/or verify proofs - parse on dedicated stack
const size_t stack_size = 54 * 1024; // 54kb seems sufficient
ret = run_in_temporary_task(stack_size, parse_psbt_bytes, &data);
+#else
+ // NOTE: devices without SPIRAM do not have sufficient free memory
+ // to parse/process any reasonable PSET.
+ // TODO: Change all callers to return an error message
+ JADE_LOGE("Cannot process PSET on a non-SPIRAM device");
+ ret = false;
+#endif
}
if (ret) {
*psbt_out = data.psbt_out;
Why this scored 40/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.