From: Alexei Starovoitov When an sk_msg prog returns SK_DROP, tcp_bpf_send_verdict() frees the full message. It then subtracts tosend bytes from *copied, the return value of sendmsg(). But tosend is the number of bytes that the verdict applies to. After bpf_msg_apply_bytes() tosend can be less than the message size. Then sendmsg() reports dropped bytes as sent. Subtract the number of bytes that sk_msg_free() frees. After an error the SK_PASS branch already does this. The SK_REDIRECT branch does the same if the message is not the cork. Nothing changes when tosend is equal to the message size. Otherwise sendmsg() now returns -EACCES if it sends nothing. Fixes: 4f738adba30a ("bpf: create tcp_bpf_ulp allowing BPF to monitor socket TX/RX data") Signed-off-by: Alexei Starovoitov --- net/ipv4/tcp_bpf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c index 072ffd8347a6..b9761af13989 100644 --- a/net/ipv4/tcp_bpf.c +++ b/net/ipv4/tcp_bpf.c @@ -513,12 +513,12 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock, break; case __SK_DROP: default: - sk_msg_free(sk, msg); + /* All of it is thrown away, not only tosend bytes */ + *copied -= sk_msg_free(sk, msg) + delta; sk_msg_apply_bytes(psock, tosend); /* The verdict holds for apply_bytes, not for ever */ if (!psock->apply_bytes) psock->eval = __SK_NONE; - *copied -= (tosend + delta); return -EACCES; } -- 2.55.0