les/utils: protect against WeightedRandomSelect overflow (#21839)

Also fixes a bug in les/flowcontrol that caused the overflow.
This commit is contained in:
Felföldi Zsolt 2020-11-23 10:18:33 +01:00 committed by GitHub
parent 3ef52775c4
commit bddf5aaa2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 0 deletions

@ -19,6 +19,7 @@ package flowcontrol
import ( import (
"fmt" "fmt"
"math"
"sync" "sync"
"time" "time"
@ -316,6 +317,9 @@ func (node *ServerNode) CanSend(maxCost uint64) (time.Duration, float64) {
node.lock.RLock() node.lock.RLock()
defer node.lock.RUnlock() defer node.lock.RUnlock()
if node.params.BufLimit == 0 {
return time.Duration(math.MaxInt64), 0
}
now := node.clock.Now() now := node.clock.Now()
node.recalcBLE(now) node.recalcBLE(now)
maxCost += uint64(safetyMargin) * node.params.MinRecharge / uint64(fcTimeConst) maxCost += uint64(safetyMargin) * node.params.MinRecharge / uint64(fcTimeConst)

@ -17,7 +17,10 @@
package utils package utils
import ( import (
"math"
"math/rand" "math/rand"
"github.com/ethereum/go-ethereum/log"
) )
type ( type (
@ -54,6 +57,14 @@ func (w *WeightedRandomSelect) IsEmpty() bool {
// setWeight sets an item's weight to a specific value (removes it if zero) // setWeight sets an item's weight to a specific value (removes it if zero)
func (w *WeightedRandomSelect) setWeight(item WrsItem, weight uint64) { func (w *WeightedRandomSelect) setWeight(item WrsItem, weight uint64) {
if weight > math.MaxInt64-w.root.sumWeight {
// old weight is still included in sumWeight, remove and check again
w.setWeight(item, 0)
if weight > math.MaxInt64-w.root.sumWeight {
log.Error("WeightedRandomSelect overflow", "sumWeight", w.root.sumWeight, "new weight", weight)
weight = math.MaxInt64 - w.root.sumWeight
}
}
idx, ok := w.idx[item] idx, ok := w.idx[item]
if ok { if ok {
w.root.setWeight(idx, weight) w.root.setWeight(idx, weight)