Skip to content

Lock reads and read-modify-write in puppetca token storage - #959

Closed
log0u7 wants to merge 1 commit into
theforeman:developfrom
log0u7:token-storage-locking
Closed

log0u7 wants to merge 1 commit into
theforeman:developfrom
log0u7:token-storage-locking

Conversation

@log0u7

@log0u7 log0u7 commented Sep 22, 2026

Copy link
Copy Markdown

Problem

TokenStorage::read had no lock: a read racing an in-progress File.write could observe an empty file, YAML.safe_load returned nil, and the next add exploded with undefined method push for nil:NilClass. add/remove also read outside the lock, so two concurrent adds could overwrite each other's update (last writer wins, tokens silently lost).

Fixes #39368

Fix

  • read takes LOCK_SH; an empty file now parses as [] (no tokens), which fails closed for CSR validation.
  • add/remove/remove_if run the read-modify-write cycle under a single LOCK_EX via a private modify helper (no nested lock, no self-deadlock).
  • parse is private and must only be called with the lock held.
  • Tests for nil push after racing read, empty-file parse, and concurrent add lost-update.

Verification

Token storage suite: 9 tests, 28 assertions, 0 failures (Ruby 3.3 container). Rubocop clean. Source-built smart-proxy image build + marker/syntax smoke checks pass in our docker/foreman pipeline.

…rage

TokenStorage::read had no lock: a read racing an in-progress File.write
could observe an empty file, YAML.safe_load returned nil, and the next
add exploded with undefined method push for nil:NilClass. add and remove
also read outside the lock, so two concurrent adds could overwrite each
other's update (last writer wins, tokens silently lost).

- read takes LOCK_SH; an empty file now parses as [] (no tokens), which
  fails closed for CSR validation
- add/remove/remove_if run the read-modify-write cycle under a single
  LOCK_EX via a private modify helper (no nested lock, no self-deadlock)
- parse is private and must only be called with the lock held
@alexjfisher

Copy link
Copy Markdown
Contributor

I'd already opened a PR for this. #945 Was it no good?

@log0u7

log0u7 commented Sep 23, 2026

Copy link
Copy Markdown
Author

My apologies, @alexjfisher - I should have checked existing PRs before opening this one. You fixed this months ago in #945, it's complete, CI-green, and honestly a better fix than mine (the atomic remove in validate_token also closes the read-then-remove window I left open). Closing mine in favor of yours. Thanks for pointing it out, and again, sorry for the noise.

@log0u7 log0u7 closed this Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants