Page MenuHomeFreeBSD

socket: Fix a race in the SO_SPLICE state machine
ClosedPublic

Authored by markj on Fri, Mar 21, 2:08 PM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Mar 27, 6:54 AM
Unknown Object (File)
Thu, Mar 27, 4:13 AM
Unknown Object (File)
Thu, Mar 27, 4:11 AM
Unknown Object (File)
Thu, Mar 27, 3:36 AM
Unknown Object (File)
Thu, Mar 27, 2:47 AM
Unknown Object (File)
Wed, Mar 26, 5:52 PM
Unknown Object (File)
Sun, Mar 23, 12:39 PM
Unknown Object (File)
Sun, Mar 23, 12:26 PM
Subscribers

Details

Summary

When so_splice() links two sockets together, it first attaches the
splice control structure to the source socket; at that point, the splice
is in the idle state. After that point, a socket wakeup will queue up
work for a splice worker thread: in particular, so_splice_dispatch()
only queues work if the splice is idle.

Meanwhile, so_splice() continues initializing the splice, and finally
calls so_splice_xfer() to transfer any already buffered data. This
assumes that the splice is still idle, but that's not true if some async
work was already dispatched.

Solve the problem by introducing an initial "under construction" state
for the splice control structure, such that wakeups won't queue any work
until so_splice() has finished.

While here, remove an outdated comment from the beginning of
so_splice_xfer().

Reported by: syzkaller
Fixes: a1da7dc1cdad ("socket: Implement SO_SPLICE")

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable