askrene: don't crash if refining flow which has capacity greaater than max it should have.
What changed, and why it matters
This patch fixes a crash in the `askrene` routing plugin for Core Lightning. In rare cases, the plugin's route-refinement logic could produce a payment flow that exceeded the estimated capacity of a path. The old code then called `abort()`, crashing the plugin. The fix replaces the crash with a warning log and a safe skip, so the node keeps running.
Apply the patch. It is a low-risk, defensive fix that prevents a plugin crash. Monitor logs for `LOG_BROKEN` messages from `askrene` after deployment, as they may indicate underlying routing-estimation issues worth investigating separately.
Security signals we found
Denial-of-service vector: plugin crash (abort) triggered by an internal routing inconsistency
Defensive hardening: replace fatal abort with logging and graceful continuation
No evidence of remote exploitability or malicious input path from the diff alone
Evidence from the diff
In plugins/askrene/refine.c, increase_flows() previously assumed capacity - flows[i]->delivers would always succeed. If a flow’s delivers amount exceeded the computed capacity ceiling, amount_msat_sub() failed and the code called abort(). The patch detects the underflow, logs a LOG_BROKEN message with the offending flow details, and continues instead of crashing. This is a defensive hardening change for an internal consistency corner case.
Changed components
plugins/askrene/refine.cincrease_flows()Core Lightning askrene routing pluginInspect captured patch +12 / −2
diff --git a/plugins/askrene/refine.c b/plugins/askrene/refine.c
index f790e00c..d6802709 100644
--- a/plugins/askrene/refine.c
+++ b/plugins/askrene/refine.c
@@ -445,8 +445,18 @@ static bool increase_flows(const struct route_query *rq,
if (amount_msat_greater(capacity, ceiling[i]))
capacity = ceiling[i];
- if (!amount_msat_sub(&remaining, capacity, flows[i]->delivers))
- abort();
+ /* We've had a report that this subtract can fail:
+ * that implies we've pushed a flow past its estimated
+ * capacity. That shouldn't happen, but if it does,
+ * we don't crash */
+ if (!amount_msat_sub(&remaining, capacity, flows[i]->delivers)) {
+ rq_log(rq, rq, LOG_BROKEN,
+ "%s: flow %s delivers %s which is more than the path's capacity %s", __func__,
+ fmt_flow_full(tmpctx, rq, flows[i]),
+ fmt_amount_msat(tmpctx, flows[i]->delivers),
+ fmt_amount_msat(tmpctx, capacity));
+ continue;
+ }
if (amount_msat_greater(remaining, best_remaining)) {
best_flownum = i;
best_remaining = remaining;
Why this scored 42/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.