Skip to content

querier: prune deleted tenants from bucket-scan metas on partial-error path (#7728) - #7778

Open
mehrdadbn9 wants to merge 6 commits into
cortexproject:masterfrom
mehrdadbn9:fix/bucket-scan-prune-deleted-tenants-7728
Open

querier: prune deleted tenants from bucket-scan metas on partial-error path (#7728)#7778
mehrdadbn9 wants to merge 6 commits into
cortexproject:masterfrom
mehrdadbn9:fix/bucket-scan-prune-deleted-tenants-7728

Conversation

@mehrdadbn9

Copy link
Copy Markdown
Contributor

What this PR does / why we need it

BucketScanBlocksFinder.scanBucket replaces its per-tenant maps wholesale only when a scan fully succeeds. On the partial-error path it merges with maps.Copy and never deletes entries, so a single tenant whose per-tenant scan permanently fails (e.g. an inaccessible customer-managed encryption key) means no scan ever fully succeeds and every tenant the process has ever seen — including long-deleted ones — is retained for the process lifetime. GetBlocks then keeps serving stale block references for deleted tenants.

This change prunes the three metas maps (userMetas / userMetasLookup / userDeletionMarks) against the active user set (userIDs, from the authoritative ScanUsers call) on the partial-error path, mirroring the fetcher eviction that evictInactiveUserFetchers already does.

Which issue(s) this PR fixes

Fixes #7728

Special notes for your reviewer

  • The active set (userIDs) is computed from a successful ScanUsers call, so it is authoritative regardless of per-tenant scan errors collected in resErrs.
  • Regression test extends TestBucketScanBlocksFinder_PeriodicScanEvictsInactiveUserDespiteOtherTenantScanError to assert the metas maps are also pruned on the error path.
NONE

Mehrdad Biukian Naeini added 6 commits August 16, 2026 03:34
trimStringByBytes scans backwards from the truncation point to find a
UTF-8 rune start, but the loop had no lower bound. When a request field
consists only of UTF-8 continuation bytes (0x80-0xBF) there is no rune
start to land on, so size underflows past zero and bytesStr[-1] panics
with 'index out of range [-1]'. Because the active query tracker is
enabled by default and the panic happens on a goroutine without recover(),
an attacker-supplied match[]/query value can crash the querier.

Bound the scan with 'size > 0' so it stops at the start of the string
instead of underflowing. When no rune start exists the field is truncated
to an empty string, which is safe.

Add TestTrimForJsonMarshalContinuationBytes covering the all-continuation-
byte case; existing multi-byte tests use valid UTF-8 ('世') which always
terminates the scan at index 0 and therefore never exercised the underflow.

Fixes cortexproject#7729

Signed-off-by: ...
Signed-off-by: Mehrdad Biukian Naeini <mehrdad.biu@mtnirancell.ir>
…roject#7731)

Signed-off-by: Mehrdad Biukian Naeini <mehrdad.biu@mtnirancell.ir>
…#7731)

Signed-off-by: Mehrdad Biukian Naeini <mehrdad.biu@mtnirancell.ir>
Signed-off-by: Mehrdad Biukian Naeini <mehrdad.biu@mtnirancell.ir>
…xproject#7730)

Signed-off-by: Mehrdad Biukian Naeini <mehrdad.biu@mtnirancell.ir>
…r path (cortexproject#7728)

Signed-off-by: Mehrdad Biukian Naeini <mehrdad.biu@mtnirancell.ir>
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.

Querier bucket-scan blocks finder: per-tenant metas maps grow unboundedly and keep serving deleted tenants while scans keep partially failing

1 participant