downgrade tool: fix invalid memory bug
What changed, and why it matters
This commit fixes a typo in a database downgrade helper tool. The bug caused the tool to pass a negative number (turned into a huge positive size) when copying data, which led to an out-of-memory (OOM) error. The fix swaps two variable names so the tool copies the already-processed chunk of data instead of the remaining chunk. It is a reliability bug in an offline maintenance tool, not a network-exploitable vulnerability.
Apply the patch. Treat this as a reliability fix rather than an urgent security update. If running the downgrade tool against production routing data, use the patched version to avoid OOM/crash and possible data corruption.
Security signals we found
Integer underflow / negative-to-size_t wrap leading to excessive allocation
Out-of-memory crash in maintenance tool
Memory corruption potential if allocation somehow succeeded
Fix is a simple source/length argument swap
Evidence from the diff
In tools/lightning-downgrade.c, convert_layer_data() calls copy_data(&out, src, len). The original code used copy_data(&out, data_in, olddata - data_in). Because data_in has been advanced past olddata, olddata - data_in is negative; when cast to a size_t it becomes a very large value, causing the OOM described in the commit message. The patch changes every instance to copy_data(&out, olddata, data_in - olddata), which is the correct positive length of the consumed prefix. The tool is used offline to downgrade routing-data store records; it is not part of the running daemon’s network or RPC path.
Changed components
tools/lightning-downgrade.cconvert_layer_data() functionCore Lightning downgrade utilityInspect captured patch +8 / −8
diff --git a/tools/lightning-downgrade.c b/tools/lightning-downgrade.c
index abe8b04..73fbaac 100644
--- a/tools/lightning-downgrade.c
+++ b/tools/lightning-downgrade.c
@@ -80,30 +80,30 @@ static const char *convert_layer_data(const tal_t *ctx,
case DSTORE_CHANNEL:
if (fromwire_dstore_channel(&data_in, &len,
&n, &n, &scid, &msat))
- copy_data(&out, data_in, olddata - data_in);
+ copy_data(&out, olddata, data_in - olddata);
continue;
case DSTORE_CHANNEL_UPDATE:
if (fromwire_dstore_channel_update(tmpctx, &data_in, &len,
&scidd, &bool_ptr,
&msat_ptr, &msat_ptr, &msat_ptr,
&u32_ptr, &u16_ptr))
- copy_data(&out, data_in, olddata - data_in);
+ copy_data(&out, olddata, data_in - olddata);
continue;
case DSTORE_CHANNEL_CONSTRAINT:
if (fromwire_dstore_channel_constraint(tmpctx, &data_in, &len,
&scidd, ×tamp,
&msat_ptr, &msat_ptr))
- copy_data(&out, data_in, olddata - data_in);
+ copy_data(&out, olddata, data_in - olddata);
continue;
case DSTORE_CHANNEL_BIAS:
if (fromwire_dstore_channel_bias(tmpctx, &data_in, &len,
&scidd, &bias,
&string))
- copy_data(&out, data_in, olddata - data_in);
+ copy_data(&out, olddata, data_in - olddata);
continue;
case DSTORE_DISABLED_NODE:
if (fromwire_dstore_disabled_node(&data_in, &len, &n))
- copy_data(&out, data_in, olddata - data_in);
+ copy_data(&out, olddata, data_in - olddata);
continue;
/* Convert back, lose timestamp */
@@ -114,7 +114,7 @@ static const char *convert_layer_data(const tal_t *ctx,
if (convert_bias)
towire_dstore_channel_bias(&out, &scidd, bias, string);
else
- copy_data(&out, data_in, olddata - data_in);
+ copy_data(&out, olddata, data_in - olddata);
}
continue;
@@ -123,7 +123,7 @@ static const char *convert_layer_data(const tal_t *ctx,
return "Askrene has a node bias, which is not supported in v25.09";
if (fromwire_dstore_node_bias(tmpctx, &data_in, &len,
&n, &string, &bias, &bias, ×tamp))
- copy_data(&out, data_in, olddata - data_in);
+ copy_data(&out, olddata, data_in - olddata);
continue;
case DSTORE_CHANNEL_IMPRESSION:
@@ -131,7 +131,7 @@ static const char *convert_layer_data(const tal_t *ctx,
&scidd, ×tamp, &msat)) {
/* We don't convert, just omit these */
if (!convert_impression)
- copy_data(&out, data_in, olddata - data_in);
+ copy_data(&out, olddata, data_in - olddata);
}
continue;
}
Why this scored 31/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.