askrene: don't leak channel intel entries
What changed, and why it matters
This commit fixes a memory leak in the askrene plugin of Core Lightning. When individual channel intelligence entries were deleted, the code removed the entry from its array but forgot to free two internal pointers (impression and constraint). Over time, this could cause the node process to consume more memory than necessary. The fix explicitly hands those pointers to a temporary context so they are cleaned up when the operation finishes.
Apply the patch. Consider running valgrind or ASan on askrene layer operations that trigger many channel_intel deletions to confirm the leak is closed and no use-after-free or double-free was introduced by the tal_steal ordering.
Security signals we found
Memory leak in plugin data structure cleanup
Missing deallocation of nested pointers before array removal
Fix located in routing/intelligence plugin (askrene)
Evidence from the diff
In plugins/askrene/layer.c, layer_trim_constraints iterates over an array of channel_intel entries and removes stale ones via tal_arr_remove. The removed element contains two tal-allocated pointers, impression and constraint, which were not being freed before the array slot was shifted/removed. The patch adds tal_steal(tmpctx, …) calls for both pointers prior to tal_arr_remove, ensuring they are released when tmpctx is freed. This is a straightforward memory-management bug fix with no direct exploit primitive visible in the diff.
Changed components
plugins/askrene/layer.clayer_trim_constraints functionchannel_intel impression and constraint fieldsInspect captured patch +5 / −0
diff --git a/plugins/askrene/layer.c b/plugins/askrene/layer.c
index cd825be9..fdfb96df 100644
--- a/plugins/askrene/layer.c
+++ b/plugins/askrene/layer.c
@@ -1213,6 +1213,11 @@ size_t layer_trim_constraints(struct layer *layer, u64 cutoff)
/* Remove from table before realloc! */
if (!changed)
channel_intel_hash_del(layer->channel_intels, intelarr);
+
+ /* The pointer inside channel_intel has to be freed. */
+ tal_steal(tmpctx, intelarr[i].impression);
+ tal_steal(tmpctx, intelarr[i].constraint);
+
tal_arr_remove(&intelarr, i);
changed = true;
num_removed++;
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.