From 5442e42cc1b0eb08d9599f9cd0fa13bffbd9f9a3 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Thu, 13 Apr 2017 14:48:11 -0700 Subject: [PATCH] routing: fix slice mutation bug that could result in an infinite loop This commit fixes a pretty nasty unnoticed bug within the main k-shortest paths algorithm loop. After a new candidate path is found, the rootPath (the path up to the pivot node) and the spurPath (the _new_ path after the pivot node) are to be combined into a new candiate shortest path. The prior logic simply appended the spurPath onto the end of the rootPath to create a slice. However, if the case that the currnet rootPath is really a sub-path in a larger slice, then this will mutate the underlying slice. This bug would manifest when doing path finding and cause an infinite loop as the slice kept growing with new spurPaths, causing the loop to never terminate. We remedy this bug by properly create a new backing slice, and adding the elements to them rather than incorrectly mutating an underlying slice. --- routing/pathfind.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/routing/pathfind.go b/routing/pathfind.go index 96985a10..c72a665c 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -530,14 +530,17 @@ func findPaths(graph *channeldb.ChannelGraph, source *channeldb.LightningNode, // Create the new combined path by concatenating the // rootPath to the spurPath. - newPath := append(rootPath, spurPath...) + newPathLen := len(rootPath) + len(spurPath) + newPath := path{ + hops: make([]*ChannelHop, 0, newPathLen), + dist: newPathLen, + } + newPath.hops = append(newPath.hops, rootPath...) + newPath.hops = append(newPath.hops, spurPath...) // We'll now add this newPath to the heap of candidate // shortest paths. - heap.Push(&candidatePaths, path{ - dist: len(newPath), - hops: newPath, - }) + heap.Push(&candidatePaths, newPath) } // If our min-heap of candidate paths is empty, then we can