Skip to content

catfile: Fix race between reading and requesting object info

Patrick Steinhardt requested to merge pks-catfile-concurrent-access into master

With the new request queue it became possible to request and read objects in separate Goroutines. Each read must be matched with a previous request, where the number of outstanding requests is tracked via an atomic integer. This integer is incremented whenever we request an object, and decremented when we read one.

There is a race in this code though: when reading object info, we update the counter by using CompareAndSwapInt64(), asserting that the existing value hasn't changed, where the intent is to detect concurrent reads on the object queue. But we cannot compare for equality here given that we may concurrently queue a request and thus increment the number of outstandin requests, which is perfectly valid. We would thus see a concurrent-access error in this case.

Fix this race by instead using AddInt64(-1) and asserting that the number of outstanding requests is not less than what we would expect. It can be equal to or more requests when there were concurrent requests, but it must never be less or otherwise it indicates concurrent reads. While this isn't as good as our previous guarantee given that it can happen that there are two reads and a request which wouldn't trigger detection, it's at least race-free.

Changelog: fixed

Merge request reports