Description
In AsyncBufferedByteIterator.swift, _AsyncBytesBuffer.Storage
(a class) conforms to Sendable
, allowing it to be passed across concurrency boundaries. Since concurrent access is allowed, classes conforming to Sendable
are responsible for implementing internal synchronization, but Storage
doesn't have any.
This means that it's possible to construct data races on the buffer of an _AsyncBytesBuffer.Storage
(through copies of an AsyncBufferedByteIterator
). (See this gist for an example.) Here's what happens:
-
Multiple instances of
_AsyncBytesBuffer
value can share a singleStorage
. If the multiple instances are read from on separate threads, then theirreadFunction
s may be called concurrently, with the same pointer argument. Since the job of thereadFunction
is to fill in the pointee bytes, there is a write/write data race on those bytes -
Similarly, one copy may be reading from the
Storage
while another is calling itsreadFunction
, producing a read/write data race on the bytes