Skip to content

les: A possible data race in setCapacity() due to inconsistent field protection #20651

@Chain-Fox

Description

@Chain-Fox

System information

Geth version: 1.9.10
OS & Version: Windows/Linux/OSX
Commit hash : 8045504

Expected behaviour

A possible data race in func setCapacity() in les/clientpool.go.
f.capLimit is read/written 9 times; 7 out of 9 times it is protected by f.lock.Lock()
; 2 out of 9 times it is read without a Lock, which are in func setCapacity().

if f.connectedCap > f.capLimit {
var kickList []*clientInfo
kick := true
f.connectedQueue.MultiPop(func(data interface{}, priority int64) bool {
client := data.(*clientInfo)
kickList = append(kickList, client)
f.connectedCap -= client.capacity
if client == c {
kick = false
}
return kick && (f.connectedCap > f.capLimit)

A data race may happen when setCapacity() and other func like setLimits are called in parallel.
I wonder if developers forgot to protect f.capLimit by f.lock.Lock() in func setCapacity() or there are some special calling rules on setCapacity() to guarantee the protection.

Actual behaviour

No, I found it through static analysis.

Steps to reproduce the behaviour

No.

Backtrace

No.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions