common: set errno=0 before calling strto{l,ul,ull}
What changed, and why it matters
This commit fixes a subtle programming bug in how Core Lightning converts text strings to numbers. Functions like strtoull only set an error flag (errno) when a value is too large, but they leave it unchanged on success. If some earlier code had already set that flag to 'overflow,' a later successful conversion of the largest possible number could be wrongly rejected as an overflow. The patch clears the error flag before each conversion so the check afterward is reliable. The practical security impact is limited because the bug only triggers when a prior operation happens to leave that specific error flag set, and the affected conversions are mostly for amounts, route hints, and JSON parsing rather than cryptographic checks.
Treat as a low-risk correctness fix. Review whether any other strto* call sites in the codebase check errno afterward without first clearing it, and apply the same pattern consistently. No urgent security response is indicated by the diff alone.
Security signals we found
Defensive fix for errno misuse around strto* conversions
Potential false-positive overflow rejection in BOLT11 amount parsing
Potential false-positive overflow rejection in JSON amount and integer parsing
No cryptographic, memory-safety, or authorization changes
Evidence from the diff
The patch sets errno = 0 immediately before calls to strtol, strtoul, strtoll, and strtoull in common/bolt11.c, common/json_parse.c, and common/json_parse_simple.c. The C standard leaves errno undefined on success for these functions, so a leftover ERANGE from an unrelated earlier library call could cause a post-call errno == ERANGE check to fire even when the conversion succeeded and returned ULLONG_MAX/ULONG_MAX. The change is defensive and corrects an edge-case misuse pattern. It does not alter parsing logic, success paths, or error handling beyond clearing errno.
Changed components
common/bolt11.c - BOLT11 invoice amount parsing (strtoull)common/json_parse.c - JSON number/bitcoin amount parsing (strtol, strtoul)common/json_parse_simple.c - JSON u64/s64/double parsing (strtoull, strtoll, strtod)Inspect captured patch +6 / −1
diff --git a/common/bolt11.c b/common/bolt11.c
index bcc00cf..bb3db5b 100644
--- a/common/bolt11.c
+++ b/common/bolt11.c
@@ -833,6 +833,7 @@ struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str,
* anything except a `multiplier` (see table above)... MUST fail the
* payment.
**/
+ errno = 0;
amount = strtoull(amountstr, &end, 10);
if (amount == ULLONG_MAX && errno == ERANGE)
return decode_fail(b11, fail,
diff --git a/common/json_parse.c b/common/json_parse.c
index 1fb1fa9..7b5c31c 100644
--- a/common/json_parse.c
+++ b/common/json_parse.c
@@ -233,6 +233,7 @@ static void parse_number(const char **guide, u32 *number)
char *endp;
long int l;
+ errno = 0;
l = strtol(*guide, &endp, 10);
assert(endp != *guide);
assert(errno != ERANGE);
@@ -518,6 +519,7 @@ bool json_to_bitcoin_amount(const char *buffer, const jsmntok_t *tok,
char *end;
unsigned long btc, sat;
+ errno = 0;
btc = strtoul(buffer + tok->start, &end, 10);
if (btc == ULONG_MAX && errno == ERANGE)
return false;
diff --git a/common/json_parse_simple.c b/common/json_parse_simple.c
index a40cb02..0842fc5 100644
--- a/common/json_parse_simple.c
+++ b/common/json_parse_simple.c
@@ -66,6 +66,7 @@ bool json_to_u64(const char *buffer, const jsmntok_t *tok, u64 *num)
char *end;
unsigned long long l;
+ errno = 0;
l = strtoull(buffer + tok->start, &end, 0);
if (end != buffer + tok->end)
return false;
@@ -88,6 +89,7 @@ bool json_to_s64(const char *buffer, const jsmntok_t *tok, s64 *num)
char *end;
long long l;
+ errno = 0;
l = strtoll(buffer + tok->start, &end, 0);
if (end != buffer + tok->end)
return false;
@@ -129,7 +131,7 @@ bool json_to_double(const char *buffer, const jsmntok_t *tok, double *num)
if (end != buffer + tok->end)
return false;
- /* Check for overflow */
+ /* Check for overflow/underflow */
if (errno == ERANGE)
return false;
Why this scored 35/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.