ccan: import new version to change vsprintfs to vsnprintfs
What changed, and why it matters
This commit updates an internal helper library (CCAN) used by Core Lightning. The headline change replaces an unsafe string-formatting call (vsprintf) with a safer bounded version (vsnprintf), and adds a new helper for adding strings of a known length. These are defensive hardening changes that reduce the risk of buffer overflows when building JSON messages, but the commit itself does not claim to fix a specific exploitable vulnerability.
Treat as routine defensive hardening. Review whether any Core Lightning callers still pass user-controlled format strings or untrusted lengths through json_out_addv, and consider adopting json_out_addstrn where fixed-length strings are emitted. No urgent patch action is indicated by the commit alone.
Security signals we found
Replacement of unbounded vsprintf with bounded vsnprintf in JSON output path
Addition of length-limited string helper json_out_addstrn
CCAN library import with no explicit security advisory or CVE referenced
No direct evidence in diff of an exploitable overflow or incident
Evidence from the diff
The diff imports a newer CCAN snapshot (init-2606 → init-2608). In ccan/ccan/json_out/json_out.c, json_out_addv now uses vsnprintf(dst + quote, fmtlen + 1, fmt, ap2) instead of vsprintf(dst + quote, fmt, ap2). A new exported function json_out_addstrn() is added to json_out.h and implemented in json_out.c, allowing callers to add a JSON string field with an explicit length. A test helper signature is adjusted (const removed). The vsprintf→vsnprintf change is a classic bounds-checking hardening measure; vsnprintf limits the number of bytes written, whereas vsprintf does not. However, the buffer was already sized to fmtlen+1 in the surrounding code, so absent a bug in fmtlen calculation this is preventive rather than a confirmed exploit fix.
Changed components
ccan/ccan/json_out/json_out.cccan/ccan/json_out/json_out.hccan/ccan/json_out/test/run.cCore Lightning JSON output / RPC message generation pathsInspect captured patch +26 / −5
diff --git a/ccan/README b/ccan/README
index 8b589bc9..e15812c1 100644
--- a/ccan/README
+++ b/ccan/README
@@ -1,3 +1,3 @@
CCAN imported from http://ccodearchive.net.
-CCAN version: init-2606-g5f219f03
+CCAN version: init-2608-gb35fabb6
diff --git a/ccan/ccan/json_out/json_out.c b/ccan/ccan/json_out/json_out.c
index 53837e67..9e371343 100644
--- a/ccan/ccan/json_out/json_out.c
+++ b/ccan/ccan/json_out/json_out.c
@@ -9,7 +9,7 @@ struct json_out {
/* Callback if we reallocate. */
void (*move_cb)(struct json_out *jout, ptrdiff_t delta, void *arg);
void *cb_arg;
-
+
#ifdef CCAN_JSON_OUT_DEBUG
/* tal_arr of types ( or [ we're enclosed in. NULL if oom. */
char *wrapping;
@@ -246,7 +246,7 @@ bool json_out_addv(struct json_out *jout,
dst = mkroom(jout, fmtlen + 1 + (int)quote*2);
if (!dst)
goto out;
- vsprintf(dst + quote, fmt, ap2);
+ vsnprintf(dst + quote, fmtlen + 1, fmt, ap2);
}
#ifdef CCAN_JSON_OUT_DEBUG
@@ -294,7 +294,14 @@ bool json_out_addstr(struct json_out *jout,
const char *fieldname,
const char *str)
{
- size_t len = strlen(str);
+ return json_out_addstrn(jout, fieldname, str, strlen(str));
+}
+
+bool json_out_addstrn(struct json_out *jout,
+ const char *fieldname,
+ const char *str,
+ size_t len)
+{
char *p;
struct json_escape *e;
diff --git a/ccan/ccan/json_out/json_out.h b/ccan/ccan/json_out/json_out.h
index da8b4ffa..eab20b7a 100644
--- a/ccan/ccan/json_out/json_out.h
+++ b/ccan/ccan/json_out/json_out.h
@@ -121,6 +121,20 @@ bool json_out_addstr(struct json_out *jout,
const char *fieldname,
const char *str);
+/**
+ * json_out_addstrn - convenience helper to add a string field (with length).
+ * @jout: the json_out object to write into.
+ * @fieldname: optional fieldname to prepend.
+ * @str: the string to add (must not be NULL).
+ * @len: the length of @str
+ *
+ * Equivalent to json_out_add(@jout, @fieldname, true, "%.*s", @len, @str);
+ */
+bool json_out_addstrn(struct json_out *jout,
+ const char *fieldname,
+ const char *str,
+ size_t len);
+
/**
* json_out_member_direct - add a field, with direct access.
* @jout: the json_out object to write into.
diff --git a/ccan/ccan/json_out/test/run.c b/ccan/ccan/json_out/test/run.c
index f6f9d41e..2fe9cbcf 100644
--- a/ccan/ccan/json_out/test/run.c
+++ b/ccan/ccan/json_out/test/run.c
@@ -69,7 +69,7 @@ static void test_json_out_add(const tal_t *ctx,
}
}
-static void json_eq(const struct json_out *jout, const char *expect)
+static void json_eq(struct json_out *jout, const char *expect)
{
size_t len;
const char *p;
Why this scored 49/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.