plugins/libplugin-pay: Add a check for NaN values
What changed, and why it matters
This commit fixes a rare numerical edge case in Core Lightning's payment routing plugin. A calculation that estimates route capacity could, in some situations, produce a special 'not a number' (NaN) value because of the imprecise half-precision floating-point type used for channel capacity limits. The patch adds a guard so that if the result is NaN, it is treated as an out-of-range score and clamped to a safe maximum. The practical security impact appears low: it only affects local route scoring, and the commit message frames it as fixing a runtime error under Undefined Behavior Sanitizer rather than an exploitable vulnerability.
Apply the patch. It is a minimal, defensive fix. No immediate incident response is warranted unless further analysis shows that a NaN route score can be triggered by an attacker-controlled channel announcement to systematically bias routing.
Security signals we found
Fixes undefined-behavior sanitizer (UBSan) runtime error
Adds NaN check on floating-point score before integer cast
Score is used in payment routing decisions, so NaN could distort path selection
No explicit security claim or CVE in commit message
Evidence from the diff
In plugins/libplugin-pay.c, route_score() computes a multiplicative route score using capacity_bias(), which operates on fp16_t (half-precision float) values derived from htlc_max. Due to fp16_t imprecision, capacity_bias() can return NaN. Multiplying NaN by msat.millisatoshis propagates NaN into score, which is then compared with 0xFFFFFFFF. In C, NaN comparisons are false, so the existing bounds check would not catch it, and the subsequent cast to u64 would produce an implementation-defined/UBSan-reported value. The patch adds score != score (the standard NaN test) alongside the existing overflow check, clamping to 0xFFFFFFFF if either condition holds.
Changed components
plugins/libplugin-pay.croute_score()capacity_bias()Inspect captured patch +1 / −1
diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c
index b296b87d..5409e00e 100644
--- a/plugins/libplugin-pay.c
+++ b/plugins/libplugin-pay.c
@@ -783,7 +783,7 @@ static u64 route_score(struct amount_msat fee,
*/
score = (capacity_bias(global_gossmap, c, dir, total) + 1)
* msat.millisatoshis; /* Raw: Weird math */
- if (score > 0xFFFFFFFF)
+ if (score != score || score > 0xFFFFFFFF)
return 0xFFFFFFFF;
/* Cast unnecessary, but be explicit! */
Why this scored 23/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.