httpfetcher.hostSems grows without bound, and VariantStorage.Delete orphans the .meta sidecar #87
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Verified against
mainat61f42e6. Two small, unrelated-but-adjacent storage/fetcher defects, each a few lines.1.
hostSemsis an unbounded map.internal/httpfetcher/httpfetcher.go:111,154-165allocates one semaphore channel per distinct upstream host and never removes it. Every new host adds an entry that lives until restart.In practice this is bounded by who can produce valid signatures or by the allowlist, so it is not remotely exploitable today. But it is unbounded in principle, it is the same shape as the disk-fill issue #51 just fixed, and an operator running with a permissive allowlist against many origins accumulates entries forever. Also relevant: any per-IP rate limiter (filed separately) will introduce a second map with exactly this shape, so it is worth establishing the pattern once.
2.
VariantStorage.Deleteleaves the.metasidecar behind.internal/imgcache/storage.go:485-494removes the variant file but notpath + ".meta", whichStorewrites at:417. Every deletion therefore leaks a small file that nothing will ever clean up.This became consequential with #51/PR #55: eviction is now a routine, high-volume operation, so an orphan per eviction accumulates indefinitely — and sidecars are not counted in the size accounting, so the leak is invisible to the very mechanism meant to bound disk usage. PR #55 added a reconciliation pass that sweeps some orphans; verify against the post-#55 code whether this specific case is already handled before writing a fix, and if it is, close this half as already-done rather than duplicating.
Definition of done
hostSemsentries are bounded — either reference-counted and removed when idle (thecontentLockpattern PR #55 introduced ininternal/imgcache/contentlock.gois a good model, and reusing its shape would be consistent), or capped with an LRU. Must remain race-free; the suite runs with-race.VariantStorage.Deleteremoves the.metasidecar alongside the variant file, treating a missing sidecar as success rather than an error.Deleteleaves no.metafile behind.make checkgreen.Coordination
Item 2 touches
internal/imgcache/storage.go, which PR #55 changes heavily — do it after #55 merges, and re-verify the finding against the merged code first.