Link: https://lore.kernel.org/bpf/20240404021001.94815-1-kerneljasonxing@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- include/linux/skmsg.h | 2 ++
- net/core/skmsg.c | 5 +----
- 2 files changed, 3 insertions(+), 4 deletions(-)
+ include/linux/skmsg.h | 2 ++
+ 1 file changed, 2 insertions(+)
-diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h
-index 4273505d309a7..f18eb6a6f7631 100644
--- a/include/linux/skmsg.h
+++ b/include/linux/skmsg.h
-@@ -462,10 +462,12 @@ static inline void sk_psock_put(struct sock *sk, struct sk_psock *psock)
+@@ -462,10 +462,12 @@ static inline void sk_psock_put(struct s
static inline void sk_psock_data_ready(struct sock *sk, struct sk_psock *psock)
{
}
static inline void psock_set_prog(struct bpf_prog **pprog,
-diff --git a/net/core/skmsg.c b/net/core/skmsg.c
-index 349a1d055a064..6bdb15b05a78d 100644
---- a/net/core/skmsg.c
-+++ b/net/core/skmsg.c
-@@ -1223,11 +1223,8 @@ static void sk_psock_verdict_data_ready(struct sock *sk)
-
- rcu_read_lock();
- psock = sk_psock(sk);
-- if (psock) {
-- read_lock_bh(&sk->sk_callback_lock);
-+ if (psock)
- sk_psock_data_ready(sk, psock);
-- read_unlock_bh(&sk->sk_callback_lock);
-- }
- rcu_read_unlock();
- }
- }
---
-2.43.0
-
+++ /dev/null
-From b8beca67eaa0d62d309047f1e0474ac189cf61f5 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 30 May 2023 19:51:49 +0000
-Subject: bpf, sockmap: Avoid potential NULL dereference in
- sk_psock_verdict_data_ready()
-
-From: Eric Dumazet <edumazet@google.com>
-
-[ Upstream commit b320a45638296b63be8d9a901ca8bc43716b1ae1 ]
-
-syzbot found sk_psock(sk) could return NULL when called
-from sk_psock_verdict_data_ready().
-
-Just make sure to handle this case.
-
-[1]
-general protection fault, probably for non-canonical address 0xdffffc000000005c: 0000 [#1] PREEMPT SMP KASAN
-KASAN: null-ptr-deref in range [0x00000000000002e0-0x00000000000002e7]
-CPU: 0 PID: 15 Comm: ksoftirqd/0 Not tainted 6.4.0-rc3-syzkaller-00588-g4781e965e655 #0
-Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/16/2023
-RIP: 0010:sk_psock_verdict_data_ready+0x19f/0x3c0 net/core/skmsg.c:1213
-Code: 4c 89 e6 e8 63 70 5e f9 4d 85 e4 75 75 e8 19 74 5e f9 48 8d bb e0 02 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 07 02 00 00 48 89 ef ff 93 e0 02 00 00 e8 29 fd
-RSP: 0018:ffffc90000147688 EFLAGS: 00010206
-RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000100
-RDX: 000000000000005c RSI: ffffffff8825ceb7 RDI: 00000000000002e0
-RBP: ffff888076518c40 R08: 0000000000000007 R09: 0000000000000000
-R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000000
-R13: 0000000000000000 R14: 0000000000008000 R15: ffff888076518c40
-FS: 0000000000000000(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000
-CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
-CR2: 00007f901375bab0 CR3: 000000004bf26000 CR4: 00000000003506f0
-DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
-DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
-Call Trace:
-<TASK>
-tcp_data_ready+0x10a/0x520 net/ipv4/tcp_input.c:5006
-tcp_data_queue+0x25d3/0x4c50 net/ipv4/tcp_input.c:5080
-tcp_rcv_established+0x829/0x1f90 net/ipv4/tcp_input.c:6019
-tcp_v4_do_rcv+0x65a/0x9c0 net/ipv4/tcp_ipv4.c:1726
-tcp_v4_rcv+0x2cbf/0x3340 net/ipv4/tcp_ipv4.c:2148
-ip_protocol_deliver_rcu+0x9f/0x480 net/ipv4/ip_input.c:205
-ip_local_deliver_finish+0x2ec/0x520 net/ipv4/ip_input.c:233
-NF_HOOK include/linux/netfilter.h:303 [inline]
-NF_HOOK include/linux/netfilter.h:297 [inline]
-ip_local_deliver+0x1ae/0x200 net/ipv4/ip_input.c:254
-dst_input include/net/dst.h:468 [inline]
-ip_rcv_finish+0x1cf/0x2f0 net/ipv4/ip_input.c:449
-NF_HOOK include/linux/netfilter.h:303 [inline]
-NF_HOOK include/linux/netfilter.h:297 [inline]
-ip_rcv+0xae/0xd0 net/ipv4/ip_input.c:569
-__netif_receive_skb_one_core+0x114/0x180 net/core/dev.c:5491
-__netif_receive_skb+0x1f/0x1c0 net/core/dev.c:5605
-process_backlog+0x101/0x670 net/core/dev.c:5933
-__napi_poll+0xb7/0x6f0 net/core/dev.c:6499
-napi_poll net/core/dev.c:6566 [inline]
-net_rx_action+0x8a9/0xcb0 net/core/dev.c:6699
-__do_softirq+0x1d4/0x905 kernel/softirq.c:571
-run_ksoftirqd kernel/softirq.c:939 [inline]
-run_ksoftirqd+0x31/0x60 kernel/softirq.c:931
-smpboot_thread_fn+0x659/0x9e0 kernel/smpboot.c:164
-kthread+0x344/0x440 kernel/kthread.c:379
-ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:308
-</TASK>
-
-Fixes: 6df7f764cd3c ("bpf, sockmap: Wake up polling after data copy")
-Reported-by: syzbot <syzkaller@googlegroups.com>
-Signed-off-by: Eric Dumazet <edumazet@google.com>
-Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-Reviewed-by: John Fastabend <john.fastabend@gmail.com>
-Link: https://lore.kernel.org/bpf/20230530195149.68145-1-edumazet@google.com
-Stable-dep-of: 6648e613226e ("bpf, skmsg: Fix NULL pointer dereference in sk_psock_skb_ingress_enqueue")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/core/skmsg.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/net/core/skmsg.c b/net/core/skmsg.c
-index 75554adef5df9..4b851a43cb0b7 100644
---- a/net/core/skmsg.c
-+++ b/net/core/skmsg.c
-@@ -1223,7 +1223,8 @@ static void sk_psock_verdict_data_ready(struct sock *sk)
-
- rcu_read_lock();
- psock = sk_psock(sk);
-- psock->saved_data_ready(sk);
-+ if (psock)
-+ psock->saved_data_ready(sk);
- rcu_read_unlock();
- }
- }
---
-2.43.0
-
+++ /dev/null
-From b7955538434060b99101a56673962f0695f0da85 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 19 Feb 2024 00:09:33 +0900
-Subject: bpf, sockmap: Fix NULL pointer dereference in
- sk_psock_verdict_data_ready()
-
-From: Shigeru Yoshida <syoshida@redhat.com>
-
-[ Upstream commit 4cd12c6065dfcdeba10f49949bffcf383b3952d8 ]
-
-syzbot reported the following NULL pointer dereference issue [1]:
-
- BUG: kernel NULL pointer dereference, address: 0000000000000000
- [...]
- RIP: 0010:0x0
- [...]
- Call Trace:
- <TASK>
- sk_psock_verdict_data_ready+0x232/0x340 net/core/skmsg.c:1230
- unix_stream_sendmsg+0x9b4/0x1230 net/unix/af_unix.c:2293
- sock_sendmsg_nosec net/socket.c:730 [inline]
- __sock_sendmsg+0x221/0x270 net/socket.c:745
- ____sys_sendmsg+0x525/0x7d0 net/socket.c:2584
- ___sys_sendmsg net/socket.c:2638 [inline]
- __sys_sendmsg+0x2b0/0x3a0 net/socket.c:2667
- do_syscall_64+0xf9/0x240
- entry_SYSCALL_64_after_hwframe+0x6f/0x77
-
-If sk_psock_verdict_data_ready() and sk_psock_stop_verdict() are called
-concurrently, psock->saved_data_ready can be NULL, causing the above issue.
-
-This patch fixes this issue by calling the appropriate data ready function
-using the sk_psock_data_ready() helper and protecting it from concurrency
-with sk->sk_callback_lock.
-
-Fixes: 6df7f764cd3c ("bpf, sockmap: Wake up polling after data copy")
-Reported-by: syzbot+fd7b34375c1c8ce29c93@syzkaller.appspotmail.com
-Signed-off-by: Shigeru Yoshida <syoshida@redhat.com>
-Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-Tested-by: syzbot+fd7b34375c1c8ce29c93@syzkaller.appspotmail.com
-Acked-by: John Fastabend <john.fastabend@gmail.com>
-Closes: https://syzkaller.appspot.com/bug?extid=fd7b34375c1c8ce29c93 [1]
-Link: https://lore.kernel.org/bpf/20240218150933.6004-1-syoshida@redhat.com
-Stable-dep-of: 6648e613226e ("bpf, skmsg: Fix NULL pointer dereference in sk_psock_skb_ingress_enqueue")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/core/skmsg.c | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/net/core/skmsg.c b/net/core/skmsg.c
-index 4b851a43cb0b7..349a1d055a064 100644
---- a/net/core/skmsg.c
-+++ b/net/core/skmsg.c
-@@ -1223,8 +1223,11 @@ static void sk_psock_verdict_data_ready(struct sock *sk)
-
- rcu_read_lock();
- psock = sk_psock(sk);
-- if (psock)
-- psock->saved_data_ready(sk);
-+ if (psock) {
-+ read_lock_bh(&sk->sk_callback_lock);
-+ sk_psock_data_ready(sk, psock);
-+ read_unlock_bh(&sk->sk_callback_lock);
-+ }
- rcu_read_unlock();
- }
- }
---
-2.43.0
-
+++ /dev/null
-From 345ad8e80d4dd3f71799f527f3eabb77d9429e2a Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 22 May 2023 19:56:11 -0700
-Subject: bpf, sockmap: Wake up polling after data copy
-
-From: John Fastabend <john.fastabend@gmail.com>
-
-[ Upstream commit 6df7f764cd3cf5a03a4a47b23be47e57e41fcd85 ]
-
-When TCP stack has data ready to read sk_data_ready() is called. Sockmap
-overwrites this with its own handler to call into BPF verdict program.
-But, the original TCP socket had sock_def_readable that would additionally
-wake up any user space waiters with sk_wake_async().
-
-Sockmap saved the callback when the socket was created so call the saved
-data ready callback and then we can wake up any epoll() logic waiting
-on the read.
-
-Note we call on 'copied >= 0' to account for returning 0 when a FIN is
-received because we need to wake up user for this as well so they
-can do the recvmsg() -> 0 and detect the shutdown.
-
-Fixes: 04919bed948dc ("tcp: Introduce tcp_read_skb()")
-Signed-off-by: John Fastabend <john.fastabend@gmail.com>
-Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
-Link: https://lore.kernel.org/bpf/20230523025618.113937-8-john.fastabend@gmail.com
-Stable-dep-of: 6648e613226e ("bpf, skmsg: Fix NULL pointer dereference in sk_psock_skb_ingress_enqueue")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/core/skmsg.c | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
-
-diff --git a/net/core/skmsg.c b/net/core/skmsg.c
-index 68418954ac492..75554adef5df9 100644
---- a/net/core/skmsg.c
-+++ b/net/core/skmsg.c
-@@ -1213,10 +1213,19 @@ static int sk_psock_verdict_recv(struct sock *sk, struct sk_buff *skb)
- static void sk_psock_verdict_data_ready(struct sock *sk)
- {
- struct socket *sock = sk->sk_socket;
-+ int copied;
-
- if (unlikely(!sock || !sock->ops || !sock->ops->read_skb))
- return;
-- sock->ops->read_skb(sk, sk_psock_verdict_recv);
-+ copied = sock->ops->read_skb(sk, sk_psock_verdict_recv);
-+ if (copied >= 0) {
-+ struct sk_psock *psock;
-+
-+ rcu_read_lock();
-+ psock = sk_psock(sk);
-+ psock->saved_data_ready(sk);
-+ rcu_read_unlock();
-+ }
- }
-
- void sk_psock_start_verdict(struct sock *sk, struct sk_psock *psock)
---
-2.43.0
-
+++ /dev/null
-From 2e55a8ad6cdcf880e5bae3a674eafefb0ac63458 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 15 Jun 2022 09:20:12 -0700
-Subject: net: Introduce a new proto_ops ->read_skb()
-
-From: Cong Wang <cong.wang@bytedance.com>
-
-[ Upstream commit 965b57b469a589d64d81b1688b38dcb537011bb0 ]
-
-Currently both splice() and sockmap use ->read_sock() to
-read skb from receive queue, but for sockmap we only read
-one entire skb at a time, so ->read_sock() is too conservative
-to use. Introduce a new proto_ops ->read_skb() which supports
-this sematic, with this we can finally pass the ownership of
-skb to recv actors.
-
-For non-TCP protocols, all ->read_sock() can be simply
-converted to ->read_skb().
-
-Signed-off-by: Cong Wang <cong.wang@bytedance.com>
-Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-Reviewed-by: John Fastabend <john.fastabend@gmail.com>
-Link: https://lore.kernel.org/bpf/20220615162014.89193-3-xiyou.wangcong@gmail.com
-Stable-dep-of: 6648e613226e ("bpf, skmsg: Fix NULL pointer dereference in sk_psock_skb_ingress_enqueue")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/net.h | 4 ++++
- include/net/tcp.h | 3 +--
- include/net/udp.h | 3 +--
- net/core/skmsg.c | 20 +++++---------------
- net/ipv4/af_inet.c | 3 ++-
- net/ipv4/tcp.c | 9 +++------
- net/ipv4/udp.c | 10 ++++------
- net/ipv6/af_inet6.c | 3 ++-
- net/unix/af_unix.c | 23 +++++++++--------------
- 9 files changed, 31 insertions(+), 47 deletions(-)
-
-diff --git a/include/linux/net.h b/include/linux/net.h
-index ba736b457a068..3e000dadeb8f3 100644
---- a/include/linux/net.h
-+++ b/include/linux/net.h
-@@ -133,6 +133,8 @@ struct module;
- struct sk_buff;
- typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *,
- unsigned int, size_t);
-+typedef int (*skb_read_actor_t)(struct sock *, struct sk_buff *);
-+
-
- struct proto_ops {
- int family;
-@@ -195,6 +197,8 @@ struct proto_ops {
- */
- int (*read_sock)(struct sock *sk, read_descriptor_t *desc,
- sk_read_actor_t recv_actor);
-+ /* This is different from read_sock(), it reads an entire skb at a time. */
-+ int (*read_skb)(struct sock *sk, skb_read_actor_t recv_actor);
- int (*sendpage_locked)(struct sock *sk, struct page *page,
- int offset, size_t size, int flags);
- int (*sendmsg_locked)(struct sock *sk, struct msghdr *msg,
-diff --git a/include/net/tcp.h b/include/net/tcp.h
-index 3047a8b3dbd1c..bdc5a16af8190 100644
---- a/include/net/tcp.h
-+++ b/include/net/tcp.h
-@@ -663,8 +663,7 @@ void tcp_get_info(struct sock *, struct tcp_info *);
- /* Read 'sendfile()'-style from a TCP socket */
- int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
- sk_read_actor_t recv_actor);
--int tcp_read_skb(struct sock *sk, read_descriptor_t *desc,
-- sk_read_actor_t recv_actor);
-+int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor);
-
- void tcp_initialize_rcv_mss(struct sock *sk);
-
-diff --git a/include/net/udp.h b/include/net/udp.h
-index 10508c66e7a19..20ae344bc1082 100644
---- a/include/net/udp.h
-+++ b/include/net/udp.h
-@@ -329,8 +329,7 @@ struct sock *__udp6_lib_lookup(struct net *net,
- struct sk_buff *skb);
- struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb,
- __be16 sport, __be16 dport);
--int udp_read_sock(struct sock *sk, read_descriptor_t *desc,
-- sk_read_actor_t recv_actor);
-+int udp_read_skb(struct sock *sk, skb_read_actor_t recv_actor);
-
- /* UDP uses skb->dev_scratch to cache as much information as possible and avoid
- * possibly multiple cache miss on dequeue()
-diff --git a/net/core/skmsg.c b/net/core/skmsg.c
-index 9cd14212dcd0b..68418954ac492 100644
---- a/net/core/skmsg.c
-+++ b/net/core/skmsg.c
-@@ -1173,21 +1173,17 @@ static void sk_psock_done_strp(struct sk_psock *psock)
- }
- #endif /* CONFIG_BPF_STREAM_PARSER */
-
--static int sk_psock_verdict_recv(read_descriptor_t *desc, struct sk_buff *skb,
-- unsigned int offset, size_t orig_len)
-+static int sk_psock_verdict_recv(struct sock *sk, struct sk_buff *skb)
- {
-- struct sock *sk = (struct sock *)desc->arg.data;
- struct sk_psock *psock;
- struct bpf_prog *prog;
- int ret = __SK_DROP;
-- int len = orig_len;
-+ int len = skb->len;
-
- /* clone here so sk_eat_skb() in tcp_read_sock does not drop our data */
- skb = skb_clone(skb, GFP_ATOMIC);
-- if (!skb) {
-- desc->error = -ENOMEM;
-+ if (!skb)
- return 0;
-- }
-
- rcu_read_lock();
- psock = sk_psock(sk);
-@@ -1217,16 +1213,10 @@ static int sk_psock_verdict_recv(read_descriptor_t *desc, struct sk_buff *skb,
- static void sk_psock_verdict_data_ready(struct sock *sk)
- {
- struct socket *sock = sk->sk_socket;
-- read_descriptor_t desc;
-
-- if (unlikely(!sock || !sock->ops || !sock->ops->read_sock))
-+ if (unlikely(!sock || !sock->ops || !sock->ops->read_skb))
- return;
--
-- desc.arg.data = sk;
-- desc.error = 0;
-- desc.count = 1;
--
-- sock->ops->read_sock(sk, &desc, sk_psock_verdict_recv);
-+ sock->ops->read_skb(sk, sk_psock_verdict_recv);
- }
-
- void sk_psock_start_verdict(struct sock *sk, struct sk_psock *psock)
-diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
-index 487f75993bf4f..f931d2534ab42 100644
---- a/net/ipv4/af_inet.c
-+++ b/net/ipv4/af_inet.c
-@@ -1050,6 +1050,7 @@ const struct proto_ops inet_stream_ops = {
- .sendpage = inet_sendpage,
- .splice_read = tcp_splice_read,
- .read_sock = tcp_read_sock,
-+ .read_skb = tcp_read_skb,
- .sendmsg_locked = tcp_sendmsg_locked,
- .sendpage_locked = tcp_sendpage_locked,
- .peek_len = tcp_peek_len,
-@@ -1077,7 +1078,7 @@ const struct proto_ops inet_dgram_ops = {
- .setsockopt = sock_common_setsockopt,
- .getsockopt = sock_common_getsockopt,
- .sendmsg = inet_sendmsg,
-- .read_sock = udp_read_sock,
-+ .read_skb = udp_read_skb,
- .recvmsg = inet_recvmsg,
- .mmap = sock_no_mmap,
- .sendpage = inet_sendpage,
-diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
-index 3647a5f08c22d..3fd4de1961a62 100644
---- a/net/ipv4/tcp.c
-+++ b/net/ipv4/tcp.c
-@@ -1705,8 +1705,7 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
- }
- EXPORT_SYMBOL(tcp_read_sock);
-
--int tcp_read_skb(struct sock *sk, read_descriptor_t *desc,
-- sk_read_actor_t recv_actor)
-+int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
- {
- struct tcp_sock *tp = tcp_sk(sk);
- u32 seq = tp->copied_seq;
-@@ -1721,7 +1720,7 @@ int tcp_read_skb(struct sock *sk, read_descriptor_t *desc,
- int used;
-
- __skb_unlink(skb, &sk->sk_receive_queue);
-- used = recv_actor(desc, skb, 0, skb->len);
-+ used = recv_actor(sk, skb);
- if (used <= 0) {
- if (!copied)
- copied = used;
-@@ -1736,9 +1735,7 @@ int tcp_read_skb(struct sock *sk, read_descriptor_t *desc,
- break;
- }
- consume_skb(skb);
-- if (!desc->count)
-- break;
-- WRITE_ONCE(tp->copied_seq, seq);
-+ break;
- }
- WRITE_ONCE(tp->copied_seq, seq);
-
-diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
-index d0387e5eee5b5..6a054bfb17850 100644
---- a/net/ipv4/udp.c
-+++ b/net/ipv4/udp.c
-@@ -1819,8 +1819,7 @@ struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned int flags,
- }
- EXPORT_SYMBOL(__skb_recv_udp);
-
--int udp_read_sock(struct sock *sk, read_descriptor_t *desc,
-- sk_read_actor_t recv_actor)
-+int udp_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
- {
- int copied = 0;
-
-@@ -1842,7 +1841,7 @@ int udp_read_sock(struct sock *sk, read_descriptor_t *desc,
- continue;
- }
-
-- used = recv_actor(desc, skb, 0, skb->len);
-+ used = recv_actor(sk, skb);
- if (used <= 0) {
- if (!copied)
- copied = used;
-@@ -1853,13 +1852,12 @@ int udp_read_sock(struct sock *sk, read_descriptor_t *desc,
- }
-
- kfree_skb(skb);
-- if (!desc->count)
-- break;
-+ break;
- }
-
- return copied;
- }
--EXPORT_SYMBOL(udp_read_sock);
-+EXPORT_SYMBOL(udp_read_skb);
-
- /*
- * This should be easy, if there is something there we
-diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
-index 8e0c33b683010..1b7749882c7ab 100644
---- a/net/ipv6/af_inet6.c
-+++ b/net/ipv6/af_inet6.c
-@@ -707,6 +707,7 @@ const struct proto_ops inet6_stream_ops = {
- .sendpage_locked = tcp_sendpage_locked,
- .splice_read = tcp_splice_read,
- .read_sock = tcp_read_sock,
-+ .read_skb = tcp_read_skb,
- .peek_len = tcp_peek_len,
- #ifdef CONFIG_COMPAT
- .compat_ioctl = inet6_compat_ioctl,
-@@ -732,7 +733,7 @@ const struct proto_ops inet6_dgram_ops = {
- .getsockopt = sock_common_getsockopt, /* ok */
- .sendmsg = inet6_sendmsg, /* retpoline's sake */
- .recvmsg = inet6_recvmsg, /* retpoline's sake */
-- .read_sock = udp_read_sock,
-+ .read_skb = udp_read_skb,
- .mmap = sock_no_mmap,
- .sendpage = sock_no_sendpage,
- .set_peek_off = sk_set_peek_off,
-diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
-index f66f867049015..bf610fad8775d 100644
---- a/net/unix/af_unix.c
-+++ b/net/unix/af_unix.c
-@@ -700,10 +700,8 @@ static ssize_t unix_stream_splice_read(struct socket *, loff_t *ppos,
- unsigned int flags);
- static int unix_dgram_sendmsg(struct socket *, struct msghdr *, size_t);
- static int unix_dgram_recvmsg(struct socket *, struct msghdr *, size_t, int);
--static int unix_read_sock(struct sock *sk, read_descriptor_t *desc,
-- sk_read_actor_t recv_actor);
--static int unix_stream_read_sock(struct sock *sk, read_descriptor_t *desc,
-- sk_read_actor_t recv_actor);
-+static int unix_read_skb(struct sock *sk, skb_read_actor_t recv_actor);
-+static int unix_stream_read_skb(struct sock *sk, skb_read_actor_t recv_actor);
- static int unix_dgram_connect(struct socket *, struct sockaddr *,
- int, int);
- static int unix_seqpacket_sendmsg(struct socket *, struct msghdr *, size_t);
-@@ -757,7 +755,7 @@ static const struct proto_ops unix_stream_ops = {
- .shutdown = unix_shutdown,
- .sendmsg = unix_stream_sendmsg,
- .recvmsg = unix_stream_recvmsg,
-- .read_sock = unix_stream_read_sock,
-+ .read_skb = unix_stream_read_skb,
- .mmap = sock_no_mmap,
- .sendpage = unix_stream_sendpage,
- .splice_read = unix_stream_splice_read,
-@@ -782,7 +780,7 @@ static const struct proto_ops unix_dgram_ops = {
- .listen = sock_no_listen,
- .shutdown = unix_shutdown,
- .sendmsg = unix_dgram_sendmsg,
-- .read_sock = unix_read_sock,
-+ .read_skb = unix_read_skb,
- .recvmsg = unix_dgram_recvmsg,
- .mmap = sock_no_mmap,
- .sendpage = sock_no_sendpage,
-@@ -2412,8 +2410,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, size_t si
- return __unix_dgram_recvmsg(sk, msg, size, flags);
- }
-
--static int unix_read_sock(struct sock *sk, read_descriptor_t *desc,
-- sk_read_actor_t recv_actor)
-+static int unix_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
- {
- int copied = 0;
-
-@@ -2428,7 +2425,7 @@ static int unix_read_sock(struct sock *sk, read_descriptor_t *desc,
- if (!skb)
- return err;
-
-- used = recv_actor(desc, skb, 0, skb->len);
-+ used = recv_actor(sk, skb);
- if (used <= 0) {
- if (!copied)
- copied = used;
-@@ -2439,8 +2436,7 @@ static int unix_read_sock(struct sock *sk, read_descriptor_t *desc,
- }
-
- kfree_skb(skb);
-- if (!desc->count)
-- break;
-+ break;
- }
-
- return copied;
-@@ -2580,13 +2576,12 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
- }
- #endif
-
--static int unix_stream_read_sock(struct sock *sk, read_descriptor_t *desc,
-- sk_read_actor_t recv_actor)
-+static int unix_stream_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
- {
- if (unlikely(sk->sk_state != TCP_ESTABLISHED))
- return -ENOTCONN;
-
-- return unix_read_sock(sk, desc, recv_actor);
-+ return unix_read_skb(sk, recv_actor);
- }
-
- static int unix_stream_read_generic(struct unix_stream_read_state *state,
---
-2.43.0
-
pinctrl-devicetree-fix-refcount-leak-in-pinctrl_dt_t.patch
regulator-mt6360-de-capitalize-devicetree-regulator-.patch
bpf-kconfig-fix-debug_info_btf_modules-kconfig-defin.patch
-tcp-introduce-tcp_read_skb.patch
-net-introduce-a-new-proto_ops-read_skb.patch
-bpf-sockmap-wake-up-polling-after-data-copy.patch
-bpf-sockmap-avoid-potential-null-dereference-in-sk_p.patch
-bpf-sockmap-fix-null-pointer-dereference-in-sk_psock.patch
bpf-skmsg-fix-null-pointer-dereference-in-sk_psock_s.patch
bpf-fix-a-verifier-verbose-message.patch
spi-hisi-kunpeng-delete-the-dump-interface-of-data-r.patch
fs-9p-drop-inodes-immediately-on-non-.l-too.patch
drm-nouveau-dp-don-t-probe-edp-ports-twice-harder.patch
net-usb-qmi_wwan-support-rolling-modules.patch
-tcp-fix-sock-skb-accounting-in-tcp_read_skb.patch
bpf-sockmap-tcp-data-stall-on-recv-before-accept.patch
bpf-sockmap-handle-fin-correctly.patch
bpf-sockmap-convert-schedule_work-into-delayed_work.patch
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- net/ipv4/tcp.c | 4 ++--
- net/ipv4/tcp_input.c | 2 ++
- net/ipv4/tcp_output.c | 4 +++-
+ net/ipv4/tcp.c | 4 ++--
+ net/ipv4/tcp_input.c | 2 ++
+ net/ipv4/tcp_output.c | 4 +++-
3 files changed, 7 insertions(+), 3 deletions(-)
-diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
-index c826db961fc08..1f858b3c9ac38 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
-@@ -2737,7 +2737,7 @@ void tcp_shutdown(struct sock *sk, int how)
+@@ -2692,7 +2692,7 @@ void tcp_shutdown(struct sock *sk, int h
/* If we've already sent a FIN, or it's a closed state, skip this. */
if ((1 << sk->sk_state) &
(TCPF_ESTABLISHED | TCPF_SYN_SENT |
/* Clear out any half completed packets. FIN if needed. */
if (tcp_close_state(sk))
tcp_send_fin(sk);
-@@ -2848,7 +2848,7 @@ void __tcp_close(struct sock *sk, long timeout)
+@@ -2803,7 +2803,7 @@ void __tcp_close(struct sock *sk, long t
* machine. State transitions:
*
* TCP_ESTABLISHED -> TCP_FIN_WAIT1
* TCP_CLOSE_WAIT -> TCP_LAST_ACK
*
* are legal only when FIN has been sent (i.e. in window),
-diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
-index e51b5d887c24b..52a9d7f96da43 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
-@@ -6543,6 +6543,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
+@@ -6543,6 +6543,8 @@ int tcp_rcv_state_process(struct sock *s
tcp_initialize_rcv_mss(sk);
tcp_fast_path_on(tp);
break;
case TCP_FIN_WAIT1: {
-diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
-index d8817d6c7b96f..0fb84e57a2d49 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -3441,7 +3441,9 @@ void tcp_send_fin(struct sock *sk)
if (unlikely(!skb))
return;
---
-2.43.0
-
+++ /dev/null
-From 4920db06394f041b049e3d13016d15577051471d Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 17 Aug 2022 12:54:42 -0700
-Subject: tcp: fix sock skb accounting in tcp_read_skb()
-
-From: Cong Wang <cong.wang@bytedance.com>
-
-[ Upstream commit e9c6e79760265f019cde39d3f2c443dfbc1395b0 ]
-
-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@syzkaller.appspotmail.com
-Tested-by: Stanislav Fomichev <sdf@google.com>
-Cc: 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>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/tcp.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
-index 3fd4de1961a62..c826db961fc08 100644
---- a/net/ipv4/tcp.c
-+++ b/net/ipv4/tcp.c
-@@ -1720,6 +1720,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.43.0
-
+++ /dev/null
-From a6e53a6990372e5fcf04b80c77bcf3eb99f7dd5f Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 15 Jun 2022 09:20:11 -0700
-Subject: tcp: Introduce tcp_read_skb()
-
-From: Cong Wang <cong.wang@bytedance.com>
-
-[ Upstream commit 04919bed948dc22a0032a9da867b7dcb8aece4ca ]
-
-This patch inroduces tcp_read_skb() based on tcp_read_sock(),
-a preparation for the next patch which actually introduces
-a new sock ops.
-
-TCP is special here, because it has tcp_read_sock() which is
-mainly used by splice(). tcp_read_sock() supports partial read
-and arbitrary offset, neither of them is needed for sockmap.
-
-Signed-off-by: Cong Wang <cong.wang@bytedance.com>
-Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-Reviewed-by: Eric Dumazet <edumazet@google.com>
-Reviewed-by: John Fastabend <john.fastabend@gmail.com>
-Link: https://lore.kernel.org/bpf/20220615162014.89193-2-xiyou.wangcong@gmail.com
-Stable-dep-of: 6648e613226e ("bpf, skmsg: Fix NULL pointer dereference in sk_psock_skb_ingress_enqueue")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/net/tcp.h | 2 ++
- net/ipv4/tcp.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 49 insertions(+)
-
-diff --git a/include/net/tcp.h b/include/net/tcp.h
-index 08923ed4278f0..3047a8b3dbd1c 100644
---- a/include/net/tcp.h
-+++ b/include/net/tcp.h
-@@ -663,6 +663,8 @@ void tcp_get_info(struct sock *, struct tcp_info *);
- /* Read 'sendfile()'-style from a TCP socket */
- int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
- sk_read_actor_t recv_actor);
-+int tcp_read_skb(struct sock *sk, read_descriptor_t *desc,
-+ sk_read_actor_t recv_actor);
-
- void tcp_initialize_rcv_mss(struct sock *sk);
-
-diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
-index 16fd3da68e9f6..3647a5f08c22d 100644
---- a/net/ipv4/tcp.c
-+++ b/net/ipv4/tcp.c
-@@ -1705,6 +1705,53 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
- }
- EXPORT_SYMBOL(tcp_read_sock);
-
-+int tcp_read_skb(struct sock *sk, read_descriptor_t *desc,
-+ sk_read_actor_t recv_actor)
-+{
-+ struct tcp_sock *tp = tcp_sk(sk);
-+ u32 seq = tp->copied_seq;
-+ struct sk_buff *skb;
-+ int copied = 0;
-+ u32 offset;
-+
-+ if (sk->sk_state == TCP_LISTEN)
-+ return -ENOTCONN;
-+
-+ while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
-+ int used;
-+
-+ __skb_unlink(skb, &sk->sk_receive_queue);
-+ used = recv_actor(desc, skb, 0, skb->len);
-+ if (used <= 0) {
-+ if (!copied)
-+ copied = used;
-+ break;
-+ }
-+ seq += used;
-+ copied += used;
-+
-+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) {
-+ consume_skb(skb);
-+ ++seq;
-+ break;
-+ }
-+ consume_skb(skb);
-+ if (!desc->count)
-+ break;
-+ WRITE_ONCE(tp->copied_seq, seq);
-+ }
-+ WRITE_ONCE(tp->copied_seq, seq);
-+
-+ tcp_rcv_space_adjust(sk);
-+
-+ /* Clean up data we have read: This will do ACK frames. */
-+ if (copied > 0)
-+ tcp_cleanup_rbuf(sk, copied);
-+
-+ return copied;
-+}
-+EXPORT_SYMBOL(tcp_read_skb);
-+
- int tcp_peek_len(struct socket *sock)
- {
- return tcp_inq(sock->sk);
---
-2.43.0
-