Skip to content

Data race on milestone finality field between IsValidPeer reader and Process writer #1735

@praetoriansentry

Description

@praetoriansentry

Concurrent access to milestone's finality field at 0x00c000262588. Read occurs in IsValidPeer (milestone.go:115) during peer validation in downloader while write happens in finality.Process (finality.go:76) when processing milestone updates. Race between sync downloader and milestone handler goroutines.

8509ba2

==================
WARNING: DATA RACE
Read at 0x00c000262588 by goroutine 4061:
  github.com/ethereum/go-ethereum/eth/downloader/whitelist.(*milestone).IsValidPeer()
      /var/lib/bor/eth/downloader/whitelist/milestone.go:115 +0x132
  github.com/ethereum/go-ethereum/eth/downloader/whitelist.(*Service).IsValidPeer()
      /var/lib/bor/eth/downloader/whitelist/service.go:104 +0x72
  github.com/ethereum/go-ethereum/eth/downloader.(*Downloader).findAncestor()
      /var/lib/bor/eth/downloader/bor_downloader.go:1080 +0x3be
  github.com/ethereum/go-ethereum/eth/downloader.(*Downloader).syncWithPeer()
      /var/lib/bor/eth/downloader/bor_downloader.go:651 +0xba4
  github.com/ethereum/go-ethereum/eth/downloader.(*Downloader).fetchHead()
      /var/lib/bor/eth/downloader/bor_downloader.go:949 +0xcf
  github.com/ethereum/go-ethereum/eth/downloader.(*Downloader).syncWithPeer()
      /var/lib/bor/eth/downloader/bor_downloader.go:548 +0x93d
  github.com/ethereum/go-ethereum/eth/downloader.(*Downloader).synchronise()
      /var/lib/bor/eth/downloader/bor_downloader.go:510 +0x959
  github.com/ethereum/go-ethereum/eth/downloader.(*Downloader).LegacySync()
      /var/lib/bor/eth/downloader/bor_downloader.go:380 +0xaa
  github.com/ethereum/go-ethereum/eth.(*handler).doSync()
      /var/lib/bor/eth/sync.go:276 +0x2e4
  github.com/ethereum/go-ethereum/eth.(*chainSyncer).startSync.func1()
      /var/lib/bor/eth/sync.go:252 +0x50

Previous write at 0x00c000262588 by goroutine 201:
  github.com/ethereum/go-ethereum/eth/downloader/whitelist.(*finality[go.shape.*uint8]).Process()
      /var/lib/bor/eth/downloader/whitelist/finality.go:76 +0xcd
  github.com/ethereum/go-ethereum/eth/downloader/whitelist.(*milestone).Process()
      /var/lib/bor/eth/downloader/whitelist/milestone.go:141 +0xd8
  github.com/ethereum/go-ethereum/eth/downloader/whitelist.(*Service).ProcessMilestone()
      /var/lib/bor/eth/downloader/whitelist/service.go:129 +0x83
  github.com/ethereum/go-ethereum/eth.(*ethHandler).handleMilestone()
      /var/lib/bor/eth/handler_bor.go:129 +0x9ee
  github.com/ethereum/go-ethereum/eth.(*Ethereum).subscribeAndHandleMilestone()
      /var/lib/bor/eth/backend.go:831 +0x1ae
  github.com/ethereum/go-ethereum/eth.(*Ethereum).startMilestoneWhitelistService()
      /var/lib/bor/eth/backend.go:731 +0x22b
  github.com/ethereum/go-ethereum/eth.(*Ethereum).Start.gowrap2()
      /var/lib/bor/eth/backend.go:690 +0x33

Goroutine 4061 (running) created at:
  github.com/ethereum/go-ethereum/eth.(*chainSyncer).startSync()
      /var/lib/bor/eth/sync.go:252 +0x124
  github.com/ethereum/go-ethereum/eth.(*chainSyncer).loop()
      /var/lib/bor/eth/sync.go:107 +0x4bb
  github.com/ethereum/go-ethereum/eth.(*handler).Start.gowrap3()
      /var/lib/bor/eth/handler.go:576 +0x33

Goroutine 201 (running) created at:
  github.com/ethereum/go-ethereum/eth.(*Ethereum).Start()
      /var/lib/bor/eth/backend.go:690 +0x22a
  github.com/ethereum/go-ethereum/node.(*Node).Start()
      /var/lib/bor/node/node.go:207 +0x42a
  fmt.Fscanf()
      /usr/local/go/src/fmt/scan.go:143 +0xdc
  fmt.Sscanf()
      /usr/local/go/src/fmt/scan.go:114 +0x184
  github.com/syndtr/goleveldb/leveldb/storage.fsParseName()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:651 +0x91
  github.com/syndtr/goleveldb/leveldb/storage.(*fileStorage).List()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:465 +0x4ee
  fmt.Fscanf()
      /usr/local/go/src/fmt/scan.go:143 +0xdc
  fmt.Sscanf()
      /usr/local/go/src/fmt/scan.go:114 +0x184
  github.com/syndtr/goleveldb/leveldb/storage.fsParseName()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:651 +0x91
  github.com/syndtr/goleveldb/leveldb/storage.(*fileStorage).List()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:465 +0x4ee
  github.com/syndtr/goleveldb/leveldb.(*DB).checkAndCleanFiles()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/db_util.go:52 +0x2ad
  github.com/syndtr/goleveldb/leveldb.openDB()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/db.go:137 +0x835
  fmt.Sscanf()
      /usr/local/go/src/fmt/scan.go:114 +0x184
  github.com/syndtr/goleveldb/leveldb/storage.fsParseName()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:651 +0x91
  github.com/syndtr/goleveldb/leveldb/storage.(*fileStorage).List()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:465 +0x4ee
  fmt.Fscanf()
      /usr/local/go/src/fmt/scan.go:143 +0xdc
  fmt.Sscanf()
      /usr/local/go/src/fmt/scan.go:114 +0x264
  github.com/syndtr/goleveldb/leveldb/storage.fsParseName()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:665 +0x18e
  fmt.(*ss).doScanf()
      /usr/local/go/src/fmt/scan.go:1230 +0x41d
  fmt.Fscanf()
      /usr/local/go/src/fmt/scan.go:143 +0xdc
  fmt.Sscanf()
      /usr/local/go/src/fmt/scan.go:114 +0x184
  github.com/syndtr/goleveldb/leveldb/storage.fsParseName()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:651 +0x91
  github.com/syndtr/goleveldb/leveldb/storage.(*fileStorage).List()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:465 +0x4ee
  fmt.Fscanf()
      /usr/local/go/src/fmt/scan.go:143 +0xdc
  fmt.Sscanf()
      /usr/local/go/src/fmt/scan.go:114 +0x184
  github.com/syndtr/goleveldb/leveldb/storage.fsParseName()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:651 +0x91
  github.com/syndtr/goleveldb/leveldb/storage.(*fileStorage).List()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:465 +0x4ee
  fmt.Fscanf()
      /usr/local/go/src/fmt/scan.go:143 +0xdc
  fmt.Sscanf()
      /usr/local/go/src/fmt/scan.go:114 +0x184
  github.com/syndtr/goleveldb/leveldb/storage.fsParseName()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:651 +0x91
  github.com/syndtr/goleveldb/leveldb/storage.(*fileStorage).List()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:465 +0x4ee
  github.com/syndtr/goleveldb/leveldb.(*DB).recoverJournal()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/db.go:492 +0xa1
  github.com/syndtr/goleveldb/leveldb.openDB()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/db.go:132 +0x81b
  github.com/syndtr/goleveldb/leveldb.Open()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/db.go:205 +0x35c
  github.com/syndtr/goleveldb/leveldb.(*session).create()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/session.go:125 +0x294
  github.com/syndtr/goleveldb/leveldb.Open()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/db.go:196 +0x295
  fmt.Fscanf()
      /usr/local/go/src/fmt/scan.go:143 +0xdc
  fmt.Sscanf()
      /usr/local/go/src/fmt/scan.go:114 +0x184
  github.com/syndtr/goleveldb/leveldb/storage.fsParseName()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:651 +0x91
  github.com/syndtr/goleveldb/leveldb/storage.(*fileStorage).List()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/storage/file_storage.go:465 +0x4ee
  github.com/syndtr/goleveldb/leveldb.(*session).recover.func1()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/session.go:134 +0xbb
  runtime.deferreturn()
      /usr/local/go/src/runtime/panic.go:610 +0x5d
  github.com/syndtr/goleveldb/leveldb.Open()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/db.go:191 +0x11b
  github.com/syndtr/goleveldb/leveldb.OpenFile()
      /go/pkg/mod/github.com/syndtr/goleveldb@v1.0.1-0.20220721030215-126854af5e6d/leveldb/db.go:227 +0x7d
  github.com/ethereum/go-ethereum/p2p/enode.newPersistentDB()
      /var/lib/bor/p2p/enode/nodedb.go:104 +0xcd
  github.com/ethereum/go-ethereum/p2p/enode.OpenDB()
      /var/lib/bor/p2p/enode/nodedb.go:86 +0x67
  github.com/ethereum/go-ethereum/p2p.(*Server).setupLocalNode()
      /var/lib/bor/p2p/server.go:502 +0x5e4
  github.com/ethereum/go-ethereum/p2p.(*Server).Start()
      /var/lib/bor/p2p/server.go:468 +0x81e
  github.com/ethereum/go-ethereum/node.(*Node).openEndpoints()
      /var/lib/bor/node/node.go:292 +0x188
  github.com/ethereum/go-ethereum/node.(*Node).Start()
      /var/lib/bor/node/node.go:193 +0x12b
  github.com/ethereum/go-ethereum/internal/cli/server.NewServer()
      /var/lib/bor/internal/cli/server/server.go:296 +0x1b7d
  github.com/cockroachdb/pebble.(*versionSet).create()
      /go/pkg/mod/github.com/cockroachdb/pebble@v1.1.2/version_set.go:187 +0x711
  github.com/cockroachdb/pebble.(*versionSet).create()
      /go/pkg/mod/github.com/cockroachdb/pebble@v1.1.2/version_set.go:181 +0x597
  github.com/cockroachdb/pebble.(*versionSet).create()
      /go/pkg/mod/github.com/cockroachdb/pebble@v1.1.2/version_set.go:176 +0x444
  github.com/cockroachdb/pebble.Open()
      /go/pkg/mod/github.com/cockroachdb/pebble@v1.1.2/open.go:263 +0x262c
  github.com/ethereum/go-ethereum/ethdb/pebble.New()
      /var/lib/bor/ethdb/pebble/pebble.go:245 +0xe04
  github.com/ethereum/go-ethereum/node.newPebbleDBDatabase()
      /var/lib/bor/node/database.go:116 +0x90
  github.com/ethereum/go-ethereum/node.openKeyValueDatabase()
      /var/lib/bor/node/database.go:91 +0x244
  github.com/ethereum/go-ethereum/node.openDatabase()
      /var/lib/bor/node/database.go:57 +0x57
  github.com/ethereum/go-ethereum/node.(*Node).OpenDatabaseWithFreezer()
      /var/lib/bor/node/node.go:817 +0x437
  github.com/ethereum/go-ethereum/eth.New()
      /var/lib/bor/eth/backend.go:151 +0x939
  github.com/ethereum/go-ethereum/internal/cli/server.NewServer()
      /var/lib/bor/internal/cli/server/server.go:208 +0x704
  github.com/ethereum/go-ethereum/internal/cli/server.(*Command).Run()
      /var/lib/bor/internal/cli/server/command.go:246 +0x24c
  github.com/mitchellh/cli.(*CLI).Run()
      /go/pkg/mod/github.com/mitchellh/cli@v1.1.5/cli.go:262 +0x68f
  github.com/ethereum/go-ethereum/internal/cli.Run()
      /var/lib/bor/internal/cli/command.go:48 +0x324
  main.main()
      /var/lib/bor/cmd/cli/main.go:12 +0x19b
==================

{
  "IPT_bytes_out": 41452488,
  "output_text": "WARNING: DATA RACE",
  "source": {
    "container": "l2-el-6-bor-heimdall-v2-rpc--cc2dc74a43364fa78255971f11d686ad",
    "name": "l2-el-6-bor-heimdall-v2-rpc--cc2dc74a43364fa78255971f11d686ad",
    "stream": "error"
  },
  "moment": {
    "input_hash": "-6278262993674989111",
    "_vtime_ticks": 2195657995497,
    "session_id": "c0ceefcd588ee0d629772f6fd9eae1ec-36-12"
  }
}

Metadata

Metadata

Assignees

No one assigned

    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