3da8ec8523
Ubuntu's latest tag updated from v5.15.60 to v5.15.64 and one advantage of them trailing upstream stable 5.15.y is that we can backport fixes of fixes that got in with that commit range. Found with the report of: git log --decorate v5.15..v5.15.73 | \ ~/gitdm/stablefixes --fixed-after v5.15.64 --regressed-before v5.15.64 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
64 lines
2.5 KiB
Diff
64 lines
2.5 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Liu Jian <liujian56@huawei.com>
|
|
Date: Tue, 9 Aug 2022 17:49:15 +0800
|
|
Subject: [PATCH] skmsg: Fix wrong last sg check in sk_msg_recvmsg()
|
|
|
|
[ Upstream commit 583585e48d965338e73e1eb383768d16e0922d73 ]
|
|
|
|
Fix one kernel NULL pointer dereference as below:
|
|
|
|
[ 224.462334] Call Trace:
|
|
[ 224.462394] __tcp_bpf_recvmsg+0xd3/0x380
|
|
[ 224.462441] ? sock_has_perm+0x78/0xa0
|
|
[ 224.462463] tcp_bpf_recvmsg+0x12e/0x220
|
|
[ 224.462494] inet_recvmsg+0x5b/0xd0
|
|
[ 224.462534] __sys_recvfrom+0xc8/0x130
|
|
[ 224.462574] ? syscall_trace_enter+0x1df/0x2e0
|
|
[ 224.462606] ? __do_page_fault+0x2de/0x500
|
|
[ 224.462635] __x64_sys_recvfrom+0x24/0x30
|
|
[ 224.462660] do_syscall_64+0x5d/0x1d0
|
|
[ 224.462709] entry_SYSCALL_64_after_hwframe+0x65/0xca
|
|
|
|
In commit 9974d37ea75f ("skmsg: Fix invalid last sg check in
|
|
sk_msg_recvmsg()"), we change last sg check to sg_is_last(),
|
|
but in sockmap redirection case (without stream_parser/stream_verdict/
|
|
skb_verdict), we did not mark the end of the scatterlist. Check the
|
|
sk_msg_alloc, sk_msg_page_add, and bpf_msg_push_data functions, they all
|
|
do not mark the end of sg. They are expected to use sg.end for end
|
|
judgment. So the judgment of '(i != msg_rx->sg.end)' is added back here.
|
|
|
|
Fixes: 9974d37ea75f ("skmsg: Fix invalid last sg check in sk_msg_recvmsg()")
|
|
Signed-off-by: Liu Jian <liujian56@huawei.com>
|
|
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
|
Acked-by: John Fastabend <john.fastabend@gmail.com>
|
|
Acked-by: Jakub Sitnicki <jakub@cloudflare.com>
|
|
Link: https://lore.kernel.org/bpf/20220809094915.150391-1-liujian56@huawei.com
|
|
Signed-off-by: Sasha Levin <sashal@kernel.org>
|
|
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|
---
|
|
net/core/skmsg.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/net/core/skmsg.c b/net/core/skmsg.c
|
|
index f50f8d95b628..23d65fe160c3 100644
|
|
--- a/net/core/skmsg.c
|
|
+++ b/net/core/skmsg.c
|
|
@@ -462,7 +462,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
|
|
|
|
if (copied == len)
|
|
break;
|
|
- } while (!sg_is_last(sge));
|
|
+ } while ((i != msg_rx->sg.end) && !sg_is_last(sge));
|
|
|
|
if (unlikely(peek)) {
|
|
msg_rx = sk_psock_next_msg(psock, msg_rx);
|
|
@@ -472,7 +472,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
|
|
}
|
|
|
|
msg_rx->sg.start = i;
|
|
- if (!sge->length && sg_is_last(sge)) {
|
|
+ if (!sge->length && (i == msg_rx->sg.end || sg_is_last(sge))) {
|
|
msg_rx = sk_psock_dequeue_msg(psock);
|
|
kfree_sk_msg(msg_rx);
|
|
}
|