3 ms·
> Normally you'd modify buffers after they've been acked at the application layer. “Normally”, with select/poll/epoll/kqueue IO, it is entirely valid to alloca
by amluto 4y ago
> Normally you'd modify buffers after they've been acked at the application layer.
“Normally”, with select/poll/epoll/kqueue IO, it is entirely valid to allocate a buffer, put some data in, call send(), and immediately free it. With IOCP or io_uring or another completion mechanism, you ought to leave the buffer alone until the network stack reports completion. None of this has anything to do with SMB or other application layers — it’s how the network stack works.
With splice(), you don’t know when to discard the buffer. Even if you add application-layer acks, you are potentially vulnerable to a misbehaving peer that acks too early. For example, if you spliced from memory (using an mmapped, file-based heap, although I don’t know why one would do this):
malloc() (from mmapped space)
fill in buffer
splice to pipe then splice to socket
wait for application layer ack
free
If the ack is a lie, you have a use-after-free.