Blame SOURCES/CVE-2023-4622.patch

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