descriptor: improve validation of child key path
What changed, and why it matters
This commit tightens how a Bitcoin hardware wallet (Blockstream Jade) validates the length of a child key path string before copying it into a fixed-size buffer. The change adds an explicit length check and uses the already-computed length rather than recomputing it after the copy. This appears to be a defensive hardening fix against a potential buffer overflow when handling wallet descriptors, though the commit message does not call it a security fix and no exploit details are provided.
Treat as a hardening fix and include in routine firmware updates. Review whether additional descriptor fields need similar length checks and consider replacing strcpy with snprintf/strlcpy for defense in depth. No urgent out-of-band response is indicated absent evidence of active exploitation.
Security signals we found
Fixed-size buffer write (strcpy into signer->path_str)
New explicit length assertion before copy
Descriptor parsing path, a common attack surface for wallet firmware
Commit message frames change as 'improve validation' rather than security fix
Evidence from the diff
In main/descriptor.c, descriptor_get_signers() copies a child key path string (from libwally) into signer->path_str, a fixed-size buffer in the signer structure. Previously the code called strcpy() and then strlen() to set path_len. The patch computes the length first, asserts it is smaller than sizeof(signer->path_str), then copies. This prevents a malformed or over-long descriptor path from overflowing signer->path_str. The change is small and partial: it does not replace strcpy() with a bounded copy, but it does add an explicit length assertion before the unbounded copy.
Changed components
main/descriptor.cdescriptor_get_signers()signer->path_str bufferInspect captured patch +3 / −1
diff --git a/main/descriptor.c b/main/descriptor.c
index f235580..d225b2d 100644
--- a/main/descriptor.c
+++ b/main/descriptor.c
@@ -414,8 +414,10 @@ bool descriptor_get_signers(const char* name, const descriptor_data_t* descripto
*errmsg = "Failed to get child path string";
goto cleanup;
}
+ const size_t child_path_len = strlen(str);
+ JADE_ASSERT(child_path_len < sizeof(signer->path_str));
strcpy(signer->path_str, str);
- signer->path_len = strlen(str);
+ signer->path_len = child_path_len;
signer->path_is_string = true;
JADE_WALLY_VERIFY(wally_free_string(str));
}
Why this scored 42/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.