From: Chris Mason psock->cork is a ring. sk_msg_memcopy_from_iter() writes at sg.curr. sk_msg_alloc() adds room at sg.end, where a full ring has a spare element. When only a part of the data fits, tcp_bpf_sendmsg() copies this part and flushes the cork. If nothing fits, it copies 0 bytes. This copy writes nothing, but it moves sg.curr to sg.end and returns -ENOSPC. Thus sendmsg() fails without a flush. sg.curr stays at sg.end, and from there a copy moves it past the spare element. Then a copy can skip the first new element, and the peer gets memory that nobody wrote. Skip the copy when sk_msg_alloc() adds nothing, as tls_sw_sendmsg_locked() does. This pass of the loop flushes the cork. The flush empties the element at sg.curr, thus the copy in the next pass starts at the first new element. Now sendmsg() on a full cork does not fail with ENOSPC. The prog runs on less data than it wants to cork, as it does when a part fits. The first Fixes tag is for the -ENOSPC without a flush. The commit in the second tag added the spare element. Since then sg.curr can move past it. Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface") Fixes: 031097d9e079 ("net: skmsg: fix TLS 1.3 crash with full sk_msg") Signed-off-by: Chris Mason Signed-off-by: Alexei Starovoitov --- net/ipv4/tcp_bpf.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c index d24ebcd7633b..a450b1ff3cfb 100644 --- a/net/ipv4/tcp_bpf.c +++ b/net/ipv4/tcp_bpf.c @@ -611,8 +611,15 @@ static int tcp_bpf_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) copy = msg_tx->sg.size - osize; } - ret = sk_msg_memcopy_from_iter(sk, &msg->msg_iter, msg_tx, - copy); + /* + * copy is 0 if the ring of the cork was full already and its + * last element could not be extended. Flush the cork below, + * and let the next pass take the data. + */ + ret = 0; + if (copy) + ret = sk_msg_memcopy_from_iter(sk, &msg->msg_iter, + msg_tx, copy); if (ret < 0) { sk_msg_trim(sk, msg_tx, osize); err = ret; -- 2.55.0