tx: prevent an asan false positive
What changed, and why it matters
This is a tiny code cleanup change. The function previously calculated 'bytes + bytes_len' and assigned it to 'end' before checking whether 'bytes' was NULL. AddressSanitizer (a debugging tool) flags arithmetic on NULL pointers even when the result is never used, which made fuzzing tests falsely report memory leaks. The patch moves that calculation to after the NULL check so the debugging tool stays quiet. There is no user-facing bug or security vulnerability being fixed here.
No security action required. Treat as normal code hygiene. If fuzzing infrastructure previously tripped on this, update to this commit to reduce noise.
Security signals we found
ASan false positive suppression
NULL pointer arithmetic avoided
No functional behavior change
No bounds-check or validation logic change
Evidence from the diff
In analyze_tx(), the original code initialized ‘end = bytes + bytes_len’ at declaration time, before validating ‘bytes’. When ‘bytes’ is NULL, this performs pointer arithmetic on NULL, which ASan reports even though ‘end’ is never dereferenced because the function returns WALLY_EINVAL immediately. The patch delays computing ‘end’ until after the input validation, and similarly rewrites the first ‘p’ assignment to use ‘bytes’ directly instead of ‘p’ (which was previously equal to bytes). This eliminates an ASan false positive during fuzzing without changing any runtime behavior for valid inputs.
Changed components
src/transaction.canalyze_tx()Inspect captured patch +4 / −3
diff --git a/src/transaction.c b/src/transaction.c
index f072547..aac98a5 100644
--- a/src/transaction.c
+++ b/src/transaction.c
@@ -2200,7 +2200,7 @@ static int analyze_tx(const unsigned char *bytes, size_t bytes_len,
uint32_t flags, size_t *num_inputs, size_t *num_outputs,
bool *expect_witnesses)
{
- const unsigned char *p = bytes, *end = bytes + bytes_len;
+ const unsigned char *p, *end;
uint64_t v, num_witnesses;
size_t i, j;
struct wally_tx tmp_tx;
@@ -2214,10 +2214,11 @@ static int analyze_tx(const unsigned char *bytes, size_t bytes_len,
*expect_witnesses = false;
if (!bytes || bytes_len < sizeof(uint32_t) + 2 || (flags & ~WALLY_TX_ALL_FLAGS) ||
- !num_inputs || !num_outputs || !expect_witnesses || p > end)
+ !num_inputs || !num_outputs || !expect_witnesses)
return WALLY_EINVAL;
- p += uint32_from_le_bytes(p, &tmp_tx.version);
+ end = bytes + bytes_len;
+ p = bytes + uint32_from_le_bytes(bytes, &tmp_tx.version);
if (is_elements) {
if (flags & WALLY_TX_FLAG_PRE_BIP144)
Why this scored 20/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.