diff --git a/net/core/skmsg.c b/net/core/skmsg.c index 2b6d9519ff29..53d0251788aa 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -1180,6 +1180,8 @@ static int sk_psock_verdict_recv(struct sock *sk, struct sk_buff *skb) int ret = __SK_DROP; int len = skb->len; + skb_get(skb); + rcu_read_lock(); psock = sk_psock(sk); if (unlikely(!psock)) { diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 849ef44f5043..6680116fdda4 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1772,6 +1772,7 @@ int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) WARN_ON_ONCE(!skb_set_owner_sk_safe(skb, sk)); tcp_flags = TCP_SKB_CB(skb)->tcp_flags; used = recv_actor(sk, skb); + consume_skb(skb); if (used < 0) { if (!copied) copied = used; diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 956d6797c76f..3ffa30c37293 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1806,7 +1806,7 @@ EXPORT_SYMBOL(__skb_recv_udp); int udp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) { struct sk_buff *skb; - int err; + int err, copied; try_again: skb = skb_recv_udp(sk, MSG_DONTWAIT, &err); @@ -1825,7 +1825,10 @@ int udp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) } WARN_ON_ONCE(!skb_set_owner_sk_safe(skb, sk)); - return recv_actor(sk, skb); + copied = recv_actor(sk, skb); + kfree_skb(skb); + + return copied; } EXPORT_SYMBOL(udp_read_skb); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 5b19b6c53a2c..70eb3bc67126 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -2552,7 +2552,7 @@ static int unix_read_skb(struct sock *sk, skb_read_actor_t recv_actor) { struct unix_sock *u = unix_sk(sk); struct sk_buff *skb; - int err; + int err, copied; mutex_lock(&u->iolock); skb = skb_recv_datagram(sk, MSG_DONTWAIT, &err); @@ -2560,7 +2560,10 @@ static int unix_read_skb(struct sock *sk, skb_read_actor_t recv_actor) if (!skb) return err; - return recv_actor(sk, skb); + copied = recv_actor(sk, skb); + kfree_skb(skb); + + return copied; } /*