On Sun, Jul 10, 2022 at 12:20 AM Cong Wang <xiyou.wangcong@xxxxxxxxx> wrote: > > From: Cong Wang <cong.wang@xxxxxxxxxxxxx> > > Before commit 965b57b469a5 ("net: Introduce a new proto_ops > ->read_skb()"), skb was not dequeued from receive queue hence > when we close TCP socket skb can be just flushed synchronously. > > After this commit, we have to uncharge skb immediately after being > dequeued, otherwise it is still charged in the original sock. And we > still need to retain skb->sk, as eBPF programs may extract sock > information from skb->sk. Therefore, we have to call > skb_set_owner_sk_safe() here. > > Fixes: 965b57b469a5 ("net: Introduce a new proto_ops ->read_skb()") > Reported-and-tested-by: syzbot+a0e6f8738b58f7654417@xxxxxxxxxxxxxxxxxxxxxxxxx > Tested-by: Stanislav Fomichev <sdf@xxxxxxxxxx> > Cc: Eric Dumazet <edumazet@xxxxxxxxxx> > Cc: John Fastabend <john.fastabend@xxxxxxxxx> > Signed-off-by: Cong Wang <cong.wang@xxxxxxxxxxxxx> > --- > net/ipv4/tcp.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c > index 9d2fd3ced21b..c6b1effb2afd 100644 > --- a/net/ipv4/tcp.c > +++ b/net/ipv4/tcp.c > @@ -1749,6 +1749,7 @@ int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) > int used; > > __skb_unlink(skb, &sk->sk_receive_queue); > + WARN_ON(!skb_set_owner_sk_safe(skb, sk)); > used = recv_actor(sk, skb); > if (used <= 0) { > if (!copied) > -- > 2.34.1 > I am reading tcp_read_skb(),it seems to have other bugs. I wonder why syzbot has not caught up yet. It ignores the offset value from tcp_recv_skb(), this looks wrong to me. The reason tcp_read_sock() passes a @len parameter is that is it not skb->len, but (skb->len - offset) Also if recv_actor(sk, skb) returns 0, we probably still need to advance tp->copied_seq, for instance if skb had a pure FIN (and thus skb->len == 0), since you removed the skb from sk_receive_queue ?