Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tcp: handle pure FIN case correctly

When skb->len==0, the recv_actor() returns 0 too, but we also use 0
for error conditions. This patch amends this by propagating the errors
to tcp_read_skb() so that we can distinguish skb->len==0 case from
error cases.

Fixes: 04919bed948d ("tcp: Introduce tcp_read_skb()")
Reported-by: Eric Dumazet <edumazet@google.com>
Cc: John Fastabend <john.fastabend@gmail.com>
Cc: Jakub Sitnicki <jakub@cloudflare.com>
Signed-off-by: Cong Wang <cong.wang@bytedance.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Cong Wang and committed by
Jakub Kicinski
2e23acd9 a8688821

+4 -3
+3 -2
net/core/skmsg.c
··· 1194 1194 ret = bpf_prog_run_pin_on_cpu(prog, skb); 1195 1195 ret = sk_psock_map_verd(ret, skb_bpf_redirect_fetch(skb)); 1196 1196 } 1197 - if (sk_psock_verdict_apply(psock, skb, ret) < 0) 1198 - len = 0; 1197 + ret = sk_psock_verdict_apply(psock, skb, ret); 1198 + if (ret < 0) 1199 + len = ret; 1199 1200 out: 1200 1201 rcu_read_unlock(); 1201 1202 return len;
+1 -1
net/ipv4/tcp.c
··· 1768 1768 __skb_unlink(skb, &sk->sk_receive_queue); 1769 1769 WARN_ON(!skb_set_owner_sk_safe(skb, sk)); 1770 1770 copied = recv_actor(sk, skb); 1771 - if (copied > 0) { 1771 + if (copied >= 0) { 1772 1772 seq += copied; 1773 1773 if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) 1774 1774 ++seq;