Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix race in tidy status with cert counting #18899

Merged
merged 3 commits into from
Jan 30, 2023

Conversation

cipherboy
Copy link
Contributor

Read total cert counts with atomic.LoadUint32(...)

When generating the tidy status, we read the values of two backend
atomics, b.certCount and b.revokedCertCount, without using the atomic
load operation. This resulted in a data race when the status was read
at the same time as an on-going tidy operation:

WARNING: DATA RACE
Write at 0x00c00c77680c by goroutine 90522:
  sync/atomic.AddInt32()
      /usr/local/go/src/runtime/race_amd64.s:281 +0xb
  sync/atomic.AddUint32()
      <autogenerated>:1 +0x1a
  github.com/hashicorp/vault/builtin/logical/pki.(*backend).tidyStatusIncRevokedCertCount()
      /home/circleci/go/src/github.com/hashicorp/vault/builtin/logical/pki/path_tidy.go:1236 +0x107
  github.com/hashicorp/vault/builtin/logical/pki.(*backend).doTidyRevocationStore()
      /home/circleci/go/src/github.com/hashicorp/vault/builtin/logical/pki/path_tidy.go:525 +0x1404
  github.com/hashicorp/vault/builtin/logical/pki.(*backend).startTidyOperation.func1.1()
      /home/circleci/go/src/github.com/hashicorp/vault/builtin/logical/pki/path_tidy.go:290 +0x1a4
  github.com/hashicorp/vault/builtin/logical/pki.(*backend).startTidyOperation.func1()
      /home/circleci/go/src/github.com/hashicorp/vault/builtin/logical/pki/path_tidy.go:342 +0x278

Previous read at 0x00c00c77680c by goroutine 90528:
  reflect.Value.Uint()
      /usr/local/go/src/reflect/value.go:2584 +0x195
  encoding/json.uintEncoder()
      /usr/local/go/src/encoding/json/encode.go:562 +0x45
  encoding/json.ptrEncoder.encode()
      /usr/local/go/src/encoding/json/encode.go:944 +0x3c2
  encoding/json.ptrEncoder.encode-fm()
      <autogenerated>:1 +0x90
  encoding/json.(*encodeState).reflectValue()
      /usr/local/go/src/encoding/json/encode.go:359 +0x88
  encoding/json.interfaceEncoder()
      /usr/local/go/src/encoding/json/encode.go:715 +0x17b
  encoding/json.mapEncoder.encode()
      /usr/local/go/src/encoding/json/encode.go:813 +0x854
  ... more stack trace pointing into JSON encoding and http
  handler...

In particular, because the tidy status was directly reading the uint
value without resorting to the atomic side, the JSON serialization could
race with a later atomic update.


Also addresses a similar case in the tests, but this shouldn't race as its at the end of the test and no tidy should still be running.

When generating the tidy status, we read the values of two backend
atomics, b.certCount and b.revokedCertCount, without using the atomic
load operation. This resulted in a data race when the status was read
at the same time as an on-going tidy operation:

    WARNING: DATA RACE
    Write at 0x00c00c77680c by goroutine 90522:
      sync/atomic.AddInt32()
          /usr/local/go/src/runtime/race_amd64.s:281 +0xb
      sync/atomic.AddUint32()
          <autogenerated>:1 +0x1a
      github.com/hashicorp/vault/builtin/logical/pki.(*backend).tidyStatusIncRevokedCertCount()
          /home/circleci/go/src/github.com/hashicorp/vault/builtin/logical/pki/path_tidy.go:1236 +0x107
      github.com/hashicorp/vault/builtin/logical/pki.(*backend).doTidyRevocationStore()
          /home/circleci/go/src/github.com/hashicorp/vault/builtin/logical/pki/path_tidy.go:525 +0x1404
      github.com/hashicorp/vault/builtin/logical/pki.(*backend).startTidyOperation.func1.1()
          /home/circleci/go/src/github.com/hashicorp/vault/builtin/logical/pki/path_tidy.go:290 +0x1a4
      github.com/hashicorp/vault/builtin/logical/pki.(*backend).startTidyOperation.func1()
          /home/circleci/go/src/github.com/hashicorp/vault/builtin/logical/pki/path_tidy.go:342 +0x278

    Previous read at 0x00c00c77680c by goroutine 90528:
      reflect.Value.Uint()
          /usr/local/go/src/reflect/value.go:2584 +0x195
      encoding/json.uintEncoder()
          /usr/local/go/src/encoding/json/encode.go:562 +0x45
      encoding/json.ptrEncoder.encode()
          /usr/local/go/src/encoding/json/encode.go:944 +0x3c2
      encoding/json.ptrEncoder.encode-fm()
          <autogenerated>:1 +0x90
      encoding/json.(*encodeState).reflectValue()
          /usr/local/go/src/encoding/json/encode.go:359 +0x88
      encoding/json.interfaceEncoder()
          /usr/local/go/src/encoding/json/encode.go:715 +0x17b
      encoding/json.mapEncoder.encode()
          /usr/local/go/src/encoding/json/encode.go:813 +0x854
      ... more stack trace pointing into JSON encoding and http
      handler...

In particular, because the tidy status was directly reading the uint
value without resorting to the atomic side, the JSON serialization could
race with a later atomic update.

Signed-off-by: Alexander Scheel <[email protected]>
Because no tidy operation is running here, it should be safe to read the
pointed value directly, but use the safer atomic.Load for consistency.

Signed-off-by: Alexander Scheel <[email protected]>
@cipherboy cipherboy added bug Used to indicate a potential bug secret/pki backport/1.12.x labels Jan 30, 2023
@cipherboy cipherboy added this to the 1.13.0-rc1 milestone Jan 30, 2023
@cipherboy cipherboy requested review from kitography, stevendpclark and a team January 30, 2023 18:36
Signed-off-by: Alexander Scheel <[email protected]>
Copy link
Contributor

@hghaf099 hghaf099 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

@cipherboy
Copy link
Contributor Author

cipherboy commented Jan 30, 2023

Per OOB discussion, the reported status value would be wrong, but we don't believe this race could cause other problems, so dropping the 1.12 backport label.

@cipherboy cipherboy merged commit d39fef0 into main Jan 30, 2023
@cipherboy
Copy link
Contributor Author

Thanks all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Used to indicate a potential bug secret/pki
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants