Skip to content

fix(limits): avoid underflow panic when Rate resets race - #1105

Open
RaphaelFakhri wants to merge 1 commit into
cloudflare:mainfrom
RaphaelFakhri:fix-limits-rate-reset-underflow
Open

RaphaelFakhri wants to merge 1 commit into
cloudflare:mainfrom
RaphaelFakhri:fix-limits-rate-reset-underflow

Conversation

@RaphaelFakhri

Copy link
Copy Markdown

Fixes #1104.

Rate::maybe_reset subtracts timestamps without checking for underflow, so concurrent callers can panic:

  • now - last_reset underflows when another thread stores a later reset time after this thread reads the clock. In release builds the wrapped value also forces a spurious reset that clears both slots.
  • now - 1000 in the sanity assert underflows when a thread loses the reset race within the first second after the Rate is created. This panics in both debug and release builds.

This change:

  • Uses saturating_sub for both subtractions. A thread that sees a newer reset time treats it as zero elapsed time and skips the reset.
  • Reuses past_ms for the two-interval check instead of subtracting again.
  • Adds test_concurrent_reset_does_not_panic, which runs eight threads against a Rate with a 1 ms interval for 500 ms.

Testing

cargo test -p pingora-limits --lib rate::tests::test_concurrent_reset_does_not_panic

Without the fix, the test fails on every run in debug and release builds. With the fix, it passes. cargo test -p pingora-limits, cargo fmt --check and cargo clippy -p pingora-limits --all-targets -- -D warnings pass.

Rate::maybe_reset subtracted timestamps without checking for underflow.
When a thread read the clock before another thread stored a later reset
time, `now - last_reset` underflowed. When a thread lost the reset race
within the first second after the Rate was created, `now - 1000`
underflowed and the sanity assert panicked, in both debug and release
builds.

Use saturating subtraction for both and add a concurrent test with a
short interval.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pingora-limits: Rate panics on subtract overflow when threads race to reset it

1 participant