|
|
835086 |
From 3709b9a67cdd88761a540b32a1f89007f0e1b5b3 Mon Sep 17 00:00:00 2001
|
|
|
835086 |
From: Ryan Sullivan <rysulliv@redhat.com>
|
|
|
835086 |
Date: Tue, 20 Feb 2024 13:30:50 -0500
|
|
|
835086 |
Subject: [KPATCH CVE-2023-4622] kpatch fixes for CVE-2023-4622
|
|
|
835086 |
|
|
|
835086 |
Kernels:
|
|
|
835086 |
3.10.0-1160.99.1.el7
|
|
|
835086 |
3.10.0-1160.102.1.el7
|
|
|
835086 |
3.10.0-1160.105.1.el7
|
|
|
835086 |
3.10.0-1160.108.1.el7
|
|
|
835086 |
|
|
|
835086 |
|
|
|
835086 |
Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-7/-/merge_requests/68
|
|
|
835086 |
Approved-by: Joe Lawrence (@joe.lawrence)
|
|
|
835086 |
Changes since last build:
|
|
|
835086 |
[x86_64]:
|
|
|
835086 |
af_unix.o: changed function: unix_stream_sendpage
|
|
|
835086 |
sch_hfsc.o: changed function: hfsc_change_class
|
|
|
835086 |
|
|
|
835086 |
[ppc64le]:
|
|
|
835086 |
af_unix.o: changed function: unix_stream_sendpage
|
|
|
835086 |
|
|
|
835086 |
---------------------------
|
|
|
835086 |
|
|
|
835086 |
Modifications: none
|
|
|
835086 |
|
|
|
835086 |
commit 5697266978cafba4a0784a2bc81588abeb3d94a8
|
|
|
835086 |
Author: Guillaume Nault <gnault@redhat.com>
|
|
|
835086 |
Date: Wed Jan 31 13:11:14 2024 +0100
|
|
|
835086 |
|
|
|
835086 |
af_unix: Fix null-ptr-deref in unix_stream_sendpage().
|
|
|
835086 |
|
|
|
835086 |
JIRA: https://issues.redhat.com/browse/RHEL-16144
|
|
|
835086 |
Upstream Status: git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
|
|
|
835086 |
CVE: CVE-2023-4622
|
|
|
835086 |
|
|
|
835086 |
commit 790c2f9d15b594350ae9bca7b236f2b1859de02c
|
|
|
835086 |
Author: Kuniyuki Iwashima <kuniyu@amazon.com>
|
|
|
835086 |
Date: Mon Aug 21 10:55:05 2023 -0700
|
|
|
835086 |
|
|
|
835086 |
af_unix: Fix null-ptr-deref in unix_stream_sendpage().
|
|
|
835086 |
|
|
|
835086 |
Bing-Jhong Billy Jheng reported null-ptr-deref in unix_stream_sendpage()
|
|
|
835086 |
with detailed analysis and a nice repro.
|
|
|
835086 |
|
|
|
835086 |
unix_stream_sendpage() tries to add data to the last skb in the peer's
|
|
|
835086 |
recv queue without locking the queue.
|
|
|
835086 |
|
|
|
835086 |
If the peer's FD is passed to another socket and the socket's FD is
|
|
|
835086 |
passed to the peer, there is a loop between them. If we close both
|
|
|
835086 |
sockets without receiving FD, the sockets will be cleaned up by garbage
|
|
|
835086 |
collection.
|
|
|
835086 |
|
|
|
835086 |
The garbage collection iterates such sockets and unlinks skb with
|
|
|
835086 |
FD from the socket's receive queue under the queue's lock.
|
|
|
835086 |
|
|
|
835086 |
So, there is a race where unix_stream_sendpage() could access an skb
|
|
|
835086 |
locklessly that is being released by garbage collection, resulting in
|
|
|
835086 |
use-after-free.
|
|
|
835086 |
|
|
|
835086 |
To avoid the issue, unix_stream_sendpage() must lock the peer's recv
|
|
|
835086 |
queue.
|
|
|
835086 |
|
|
|
835086 |
Note the issue does not exist in 6.5+ thanks to the recent sendpage()
|
|
|
835086 |
refactoring.
|
|
|
835086 |
|
|
|
835086 |
This patch is originally written by Linus Torvalds.
|
|
|
835086 |
|
|
|
835086 |
BUG: unable to handle page fault for address: ffff988004dd6870
|
|
|
835086 |
PF: supervisor read access in kernel mode
|
|
|
835086 |
PF: error_code(0x0000) - not-present page
|
|
|
835086 |
PGD 0 P4D 0
|
|
|
835086 |
PREEMPT SMP PTI
|
|
|
835086 |
CPU: 4 PID: 297 Comm: garbage_uaf Not tainted 6.1.46 #1
|
|
|
835086 |
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
|
|
|
835086 |
RIP: 0010:kmem_cache_alloc_node+0xa2/0x1e0
|
|
|
835086 |
Code: c0 0f 84 32 01 00 00 41 83 fd ff 74 10 48 8b 00 48 c1 e8 3a 41 39 c5 0f 85 1c 01 00 00 41 8b 44 24 28 49 8b 3c 24 48 8d 4a 40 <49> 8b 1c 06 4c 89 f0 65 48 0f c7 0f 0f 94 c0 84 c0 74 a1 41 8b 44
|
|
|
835086 |
RSP: 0018:ffffc9000079fac0 EFLAGS: 00000246
|
|
|
835086 |
RAX: 0000000000000070 RBX: 0000000000000005 RCX: 000000000001a284
|
|
|
835086 |
RDX: 000000000001a244 RSI: 0000000000400cc0 RDI: 000000000002eee0
|
|
|
835086 |
RBP: 0000000000400cc0 R08: 0000000000400cc0 R09: 0000000000000003
|
|
|
835086 |
R10: 0000000000000001 R11: 0000000000000000 R12: ffff888003970f00
|
|
|
835086 |
R13: 00000000ffffffff R14: ffff988004dd6800 R15: 00000000000000e8
|
|
|
835086 |
FS: 00007f174d6f3600(0000) GS:ffff88807db00000(0000) knlGS:0000000000000000
|
|
|
835086 |
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
|
|
835086 |
CR2: ffff988004dd6870 CR3: 00000000092be000 CR4: 00000000007506e0
|
|
|
835086 |
PKRU: 55555554
|
|
|
835086 |
Call Trace:
|
|
|
835086 |
<TASK>
|
|
|
835086 |
? __die_body.cold+0x1a/0x1f
|
|
|
835086 |
? page_fault_oops+0xa9/0x1e0
|
|
|
835086 |
? fixup_exception+0x1d/0x310
|
|
|
835086 |
? exc_page_fault+0xa8/0x150
|
|
|
835086 |
? asm_exc_page_fault+0x22/0x30
|
|
|
835086 |
? kmem_cache_alloc_node+0xa2/0x1e0
|
|
|
835086 |
? __alloc_skb+0x16c/0x1e0
|
|
|
835086 |
__alloc_skb+0x16c/0x1e0
|
|
|
835086 |
alloc_skb_with_frags+0x48/0x1e0
|
|
|
835086 |
sock_alloc_send_pskb+0x234/0x270
|
|
|
835086 |
unix_stream_sendmsg+0x1f5/0x690
|
|
|
835086 |
sock_sendmsg+0x5d/0x60
|
|
|
835086 |
____sys_sendmsg+0x210/0x260
|
|
|
835086 |
___sys_sendmsg+0x83/0xd0
|
|
|
835086 |
? kmem_cache_alloc+0xc6/0x1c0
|
|
|
835086 |
? avc_disable+0x20/0x20
|
|
|
835086 |
? percpu_counter_add_batch+0x53/0xc0
|
|
|
835086 |
? alloc_empty_file+0x5d/0xb0
|
|
|
835086 |
? alloc_file+0x91/0x170
|
|
|
835086 |
? alloc_file_pseudo+0x94/0x100
|
|
|
835086 |
? __fget_light+0x9f/0x120
|
|
|
835086 |
__sys_sendmsg+0x54/0xa0
|
|
|
835086 |
do_syscall_64+0x3b/0x90
|
|
|
835086 |
entry_SYSCALL_64_after_hwframe+0x69/0xd3
|
|
|
835086 |
RIP: 0033:0x7f174d639a7d
|
|
|
835086 |
Code: 28 89 54 24 1c 48 89 74 24 10 89 7c 24 08 e8 8a c1 f4 ff 8b 54 24 1c 48 8b 74 24 10 41 89 c0 8b 7c 24 08 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 33 44 89 c7 48 89 44 24 08 e8 de c1 f4 ff 48
|
|
|
835086 |
RSP: 002b:00007ffcb563ea50 EFLAGS: 00000293 ORIG_RAX: 000000000000002e
|
|
|
835086 |
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f174d639a7d
|
|
|
835086 |
RDX: 0000000000000000 RSI: 00007ffcb563eab0 RDI: 0000000000000007
|
|
|
835086 |
RBP: 00007ffcb563eb10 R08: 0000000000000000 R09: 00000000ffffffff
|
|
|
835086 |
R10: 00000000004040a0 R11: 0000000000000293 R12: 00007ffcb563ec28
|
|
|
835086 |
R13: 0000000000401398 R14: 0000000000403e00 R15: 00007f174d72c000
|
|
|
835086 |
</TASK>
|
|
|
835086 |
|
|
|
835086 |
Fixes: 869e7c62486e ("net: af_unix: implement stream sendpage support")
|
|
|
835086 |
Reported-by: Bing-Jhong Billy Jheng <billy@starlabs.sg>
|
|
|
835086 |
Reviewed-by: Bing-Jhong Billy Jheng <billy@starlabs.sg>
|
|
|
835086 |
Co-developed-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
|
835086 |
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
|
835086 |
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
|
|
|
835086 |
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
|
835086 |
|
|
|
835086 |
Signed-off-by: Guillaume Nault <gnault@redhat.com>
|
|
|
835086 |
|
|
|
835086 |
Signed-off-by: Ryan Sullivan <rysulliv@redhat.com>
|
|
|
835086 |
---
|
|
|
835086 |
net/unix/af_unix.c | 9 ++++-----
|
|
|
835086 |
1 file changed, 4 insertions(+), 5 deletions(-)
|
|
|
835086 |
|
|
|
835086 |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
|
|
|
835086 |
index a264b4598872..033986a95c3d 100644
|
|
|
835086 |
--- a/net/unix/af_unix.c
|
|
|
835086 |
+++ b/net/unix/af_unix.c
|
|
|
835086 |
@@ -1960,6 +1960,7 @@ static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
|
|
|
835086 |
|
|
|
835086 |
if (false) {
|
|
|
835086 |
alloc_skb:
|
|
|
835086 |
+ spin_unlock(&other->sk_receive_queue.lock);
|
|
|
835086 |
unix_state_unlock(other);
|
|
|
835086 |
mutex_unlock(&unix_sk(other)->iolock);
|
|
|
835086 |
newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
|
|
|
835086 |
@@ -1999,6 +2000,7 @@ alloc_skb:
|
|
|
835086 |
init_scm = false;
|
|
|
835086 |
}
|
|
|
835086 |
|
|
|
835086 |
+ spin_lock(&other->sk_receive_queue.lock);
|
|
|
835086 |
skb = skb_peek_tail(&other->sk_receive_queue);
|
|
|
835086 |
if (tail && tail == skb) {
|
|
|
835086 |
skb = newskb;
|
|
|
835086 |
@@ -2029,14 +2031,11 @@ alloc_skb:
|
|
|
835086 |
atomic_add(size, &sk->sk_wmem_alloc);
|
|
|
835086 |
|
|
|
835086 |
if (newskb) {
|
|
|
835086 |
- err = unix_scm_to_skb(&scm, skb, false);
|
|
|
835086 |
- if (err)
|
|
|
835086 |
- goto err_state_unlock;
|
|
|
835086 |
- spin_lock(&other->sk_receive_queue.lock);
|
|
|
835086 |
+ unix_scm_to_skb(&scm, skb, false);
|
|
|
835086 |
__skb_queue_tail(&other->sk_receive_queue, newskb);
|
|
|
835086 |
- spin_unlock(&other->sk_receive_queue.lock);
|
|
|
835086 |
}
|
|
|
835086 |
|
|
|
835086 |
+ spin_unlock(&other->sk_receive_queue.lock);
|
|
|
835086 |
unix_state_unlock(other);
|
|
|
835086 |
mutex_unlock(&unix_sk(other)->iolock);
|
|
|
835086 |
|
|
|
835086 |
--
|
|
|
835086 |
2.44.0
|
|
|
835086 |
|
|
|
835086 |
|