Skip to content

[verifier] Data race in BCCSP #475

Description

@liran-funaro

Detected via local testing.


Root Cause:
The data race occurred in TestParseLifecycleEndorsementPolicy due to concurrent access to the BCCSP factory's global state:

  • Goroutine 48 (line 130): Called workload.NewPolicyEndorserFromMsp() which triggered factory.InitFactories() - writing to global factory state
  • Goroutine 51 (line 148): Called createTestBundle() which used factory.GetDefault() - reading from global factory state

Both subtests run in parallel (t.Parallel()), causing a race between initialization (write) and access (read) of the shared factory state.

Solution:
Added factory initialization before parallel subtests begin (line 122):

func TestParseLifecycleEndorsementPolicy(t *testing.T) {
	t.Parallel()

	// Initialize factory before parallel subtests to avoid data race
	_ = factory.GetDefault()

	t.Run("valid bundle returns verifier", func(t *testing.T) {
		t.Parallel()
		// ... rest of test

This ensures the sync.Once initialization in InitFactories() completes before any parallel subtest accesses the factory, eliminating the race condition.


==================
WARNING: DATA RACE
Write at 0x00000232b870 by goroutine 48:
  github.com/hyperledger/fabric-lib-go/bccsp/factory.initFactories()
      /home/liran/go/pkg/mod/github.com/hyperledger/fabric-lib-go@v1.1.3-0.20240523144151-25edd1eaf5f5/bccsp/factory/nopkcs11.go:58 +0x43a
  github.com/hyperledger/fabric-x-common/msp.GetLocalMspConfig.InitFactories.func1()
      /home/liran/go/pkg/mod/github.com/hyperledger/fabric-lib-go@v1.1.3-0.20240523144151-25edd1eaf5f5/bccsp/factory/nopkcs11.go:34 +0x2e
  sync.(*Once).doSlow()
      /home/liran/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.0.linux-amd64/src/sync/once.go:78 +0xd1
  sync.(*Once).Do()
      /home/liran/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.0.linux-amd64/src/sync/once.go:69 +0x44
  github.com/hyperledger/fabric-lib-go/bccsp/factory.InitFactories()
      /home/liran/go/pkg/mod/github.com/hyperledger/fabric-lib-go@v1.1.3-0.20240523144151-25edd1eaf5f5/bccsp/factory/nopkcs11.go:33 +0x6bd
  github.com/hyperledger/fabric-x-common/msp.GetLocalMspConfig()
      /home/liran/go/pkg/mod/github.com/hyperledger/fabric-x-common@v0.1.1-0.20260322093042-6a85243b44fa/msp/configbuilder.go:177 +0x6be
  github.com/hyperledger/fabric-x-common/msp.LoadLocalMspDir()
      /home/liran/go/pkg/mod/github.com/hyperledger/fabric-x-common@v0.1.1-0.20260322093042-6a85243b44fa/msp/factory.go:100 +0x244
  github.com/hyperledger/fabric-x-committer/utils/testcrypto.GetSigningIdentities()
      /home/liran/workspace/fabric-x-committer/utils/testcrypto/load_crypto.go:32 +0x104
  github.com/hyperledger/fabric-x-committer/utils/testcrypto.GetPeersIdentities()
      /home/liran/workspace/fabric-x-committer/utils/testcrypto/load_crypto.go:20 +0x38
  github.com/hyperledger/fabric-x-committer/loadgen/workload.NewPolicyEndorserFromMsp()
      /home/liran/workspace/fabric-x-committer/loadgen/workload/sign.go:118 +0x4e
  github.com/hyperledger/fabric-x-committer/service/verifier/policy.TestParseLifecycleEndorsementPolicy.func1()
      /home/liran/workspace/fabric-x-committer/service/verifier/policy/policy_test.go:130 +0xc4
  testing.tRunner()
      /home/liran/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.0.linux-amd64/src/testing/testing.go:2036 +0x21c
  testing.(*T).Run.gowrap1()
      /home/liran/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.0.linux-amd64/src/testing/testing.go:2101 +0x38

Previous read at 0x00000232b870 by goroutine 51:
  github.com/hyperledger/fabric-lib-go/bccsp/factory.GetDefault()
      /home/liran/go/pkg/mod/github.com/hyperledger/fabric-lib-go@v1.1.3-0.20240523144151-25edd1eaf5f5/bccsp/factory/factory.go:43 +0x27
  github.com/hyperledger/fabric-x-committer/service/verifier/policy.createTestBundle()
      /home/liran/workspace/fabric-x-committer/service/verifier/policy/policy_test.go:202 +0x169
  github.com/hyperledger/fabric-x-committer/service/verifier/policy.TestParseLifecycleEndorsementPolicy.func2()
      /home/liran/workspace/fabric-x-committer/service/verifier/policy/policy_test.go:148 +0x4b
  testing.tRunner()
      /home/liran/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.0.linux-amd64/src/testing/testing.go:2036 +0x21c
  testing.(*T).Run.gowrap1()
      /home/liran/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.0.linux-amd64/src/testing/testing.go:2101 +0x38

Goroutine 48 (running) created at:
  testing.(*T).Run()
      /home/liran/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.0.linux-amd64/src/testing/testing.go:2101 +0xb12
  github.com/hyperledger/fabric-x-committer/service/verifier/policy.TestParseLifecycleEndorsementPolicy()
      /home/liran/workspace/fabric-x-committer/service/verifier/policy/policy_test.go:121 +0x44
  testing.tRunner()
      /home/liran/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.0.linux-amd64/src/testing/testing.go:2036 +0x21c
  testing.(*T).Run.gowrap1()
      /home/liran/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.0.linux-amd64/src/testing/testing.go:2101 +0x38

Goroutine 51 (running) created at:
  testing.(*T).Run()
      /home/liran/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.0.linux-amd64/src/testing/testing.go:2101 +0xb12
  github.com/hyperledger/fabric-x-committer/service/verifier/policy.TestParseLifecycleEndorsementPolicy()
      /home/liran/workspace/fabric-x-committer/service/verifier/policy/policy_test.go:146 +0x64
  testing.tRunner()
      /home/liran/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.0.linux-amd64/src/testing/testing.go:2036 +0x21c
  testing.(*T).Run.gowrap1()
      /home/liran/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.0.linux-amd64/src/testing/testing.go:2101 +0x38
==================

Metadata

Metadata

Assignees

Labels

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions