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")