Blame SOURCES/CVE-2022-2959.patch

cf3d8e
From cd24a1fbd0abbaed922df6f88a4c166642240c18 Mon Sep 17 00:00:00 2001
cf3d8e
From: Yannick Cote <ycote@redhat.com>
cf3d8e
Date: Mon, 12 Dec 2022 12:34:49 -0500
cf3d8e
Subject: [KPATCH CVE-2022-2959] kpatch fixes for CVE-2022-2959
cf3d8e
cf3d8e
Kernels:
cf3d8e
5.14.0-162.6.1.el9_1
cf3d8e
cf3d8e
cf3d8e
Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-9/-/merge_requests/12
cf3d8e
Approved-by: Joe Lawrence (@joe.lawrence)
cf3d8e
Changes since last build:
cf3d8e
[x86_64]:
cf3d8e
ax88179_178a.o: changed function: ax88179_rx_fixup
cf3d8e
callback_xdr.o: changed function: nfs_callback_dispatch
cf3d8e
intel_gt.o: changed function: intel_gt_invalidate_tlbs
cf3d8e
nfs3proc.o: changed function: nfsd3_init_dirlist_pages
cf3d8e
nfs3proc.o: changed function: nfsd3_proc_read
cf3d8e
nfsproc.o: changed function: nfsd_proc_read
cf3d8e
nfsproc.o: changed function: nfsd_proc_readdir
cf3d8e
nfssvc.o: changed function: nfsd_dispatch
cf3d8e
pipe.o: changed function: pipe_resize_ring
cf3d8e
svc.o: changed function: nlmsvc_dispatch
cf3d8e
cf3d8e
[ppc64le]:
cf3d8e
ax88179_178a.o: changed function: ax88179_rx_fixup
cf3d8e
callback_xdr.o: changed function: nfs_callback_dispatch
cf3d8e
nfs3proc.o: changed function: nfsd3_init_dirlist_pages
cf3d8e
nfs3proc.o: changed function: nfsd3_proc_read
cf3d8e
nfsproc.o: changed function: nfsd_proc_read
cf3d8e
nfsproc.o: changed function: nfsd_proc_readdir
cf3d8e
nfssvc.o: changed function: nfsd_dispatch
cf3d8e
pipe.o: changed function: pipe_resize_ring
cf3d8e
svc.o: changed function: nlmsvc_dispatch
cf3d8e
cf3d8e
---------------------------
cf3d8e
cf3d8e
Modifications: none
cf3d8e
cf3d8e
commit c08a6dbfd89b0d7dfbc0726eeee3bb7289b59af8
cf3d8e
Author: Ian Kent <ikent@redhat.com>
cf3d8e
Date:   Tue Nov 15 14:08:25 2022 +0800
cf3d8e
cf3d8e
    pipe: Fix missing lock in pipe_resize_ring()
cf3d8e
cf3d8e
    Bugzilla: https://bugzilla.redhat.com/2141631
cf3d8e
    CVE: CVE-2022-2959
cf3d8e
    Y-Commit: 713162e02d3aca87567fc906879e972491ca045d
cf3d8e
cf3d8e
    O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2141632
cf3d8e
    Status: Linus
cf3d8e
    O-CVE: CVE-2022-2959
cf3d8e
cf3d8e
    commit 189b0ddc245139af81198d1a3637cac74f96e13a
cf3d8e
    From: David Howells <dhowells@redhat.com>
cf3d8e
    Date: 2022-05-26 07:34:52 +0100
cf3d8e
cf3d8e
            pipe: Fix missing lock in pipe_resize_ring()
cf3d8e
cf3d8e
            pipe_resize_ring() needs to take the pipe->rd_wait.lock spinlock to
cf3d8e
            prevent post_one_notification() from trying to insert into the ring
cf3d8e
            whilst the ring is being replaced.
cf3d8e
cf3d8e
            The occupancy check must be done after the lock is taken, and the lock
cf3d8e
            must be taken after the new ring is allocated.
cf3d8e
cf3d8e
            The bug can lead to an oops looking something like:
cf3d8e
cf3d8e
             BUG: KASAN: use-after-free in post_one_notification.isra.0+0x62e/0x840
cf3d8e
             Read of size 4 at addr ffff88801cc72a70 by task poc/27196
cf3d8e
             ...
cf3d8e
             Call Trace:
cf3d8e
              post_one_notification.isra.0+0x62e/0x840
cf3d8e
              __post_watch_notification+0x3b7/0x650
cf3d8e
              key_create_or_update+0xb8b/0xd20
cf3d8e
              __do_sys_add_key+0x175/0x340
cf3d8e
              __x64_sys_add_key+0xbe/0x140
cf3d8e
              do_syscall_64+0x5c/0xc0
cf3d8e
              entry_SYSCALL_64_after_hwframe+0x44/0xae
cf3d8e
cf3d8e
            Reported by Selim Enes Karaduman @Enesdex working with Trend Micro Zero
cf3d8e
            Day Initiative.
cf3d8e
cf3d8e
            Fixes: c73be61cede5 ("pipe: Add general notification queue support")
cf3d8e
            Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-17291
cf3d8e
            Signed-off-by: David Howells <dhowells@redhat.com>
cf3d8e
            Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
cf3d8e
cf3d8e
    Signed-off-by: Ian Kent <ikent@redhat.com>
cf3d8e
    Signed-off-by: Patrick Talbert <ptalbert@redhat.com>
cf3d8e
cf3d8e
Signed-off-by: Yannick Cote <ycote@redhat.com>
cf3d8e
---
cf3d8e
 fs/pipe.c | 31 ++++++++++++++++++-------------
cf3d8e
 1 file changed, 18 insertions(+), 13 deletions(-)
cf3d8e
cf3d8e
diff --git a/fs/pipe.c b/fs/pipe.c
cf3d8e
index 751d5b36c84b..4a1c6ef9493d 100644
cf3d8e
--- a/fs/pipe.c
cf3d8e
+++ b/fs/pipe.c
cf3d8e
@@ -1244,30 +1244,33 @@ unsigned int round_pipe_size(unsigned long size)
cf3d8e
 
cf3d8e
 /*
cf3d8e
  * Resize the pipe ring to a number of slots.
cf3d8e
+ *
cf3d8e
+ * Note the pipe can be reduced in capacity, but only if the current
cf3d8e
+ * occupancy doesn't exceed nr_slots; if it does, EBUSY will be
cf3d8e
+ * returned instead.
cf3d8e
  */
cf3d8e
 int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
cf3d8e
 {
cf3d8e
 	struct pipe_buffer *bufs;
cf3d8e
 	unsigned int head, tail, mask, n;
cf3d8e
 
cf3d8e
-	/*
cf3d8e
-	 * We can shrink the pipe, if arg is greater than the ring occupancy.
cf3d8e
-	 * Since we don't expect a lot of shrink+grow operations, just free and
cf3d8e
-	 * allocate again like we would do for growing.  If the pipe currently
cf3d8e
-	 * contains more buffers than arg, then return busy.
cf3d8e
-	 */
cf3d8e
-	mask = pipe->ring_size - 1;
cf3d8e
-	head = pipe->head;
cf3d8e
-	tail = pipe->tail;
cf3d8e
-	n = pipe_occupancy(pipe->head, pipe->tail);
cf3d8e
-	if (nr_slots < n)
cf3d8e
-		return -EBUSY;
cf3d8e
-
cf3d8e
 	bufs = kcalloc(nr_slots, sizeof(*bufs),
cf3d8e
 		       GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
cf3d8e
 	if (unlikely(!bufs))
cf3d8e
 		return -ENOMEM;
cf3d8e
 
cf3d8e
+	spin_lock_irq(&pipe->rd_wait.lock);
cf3d8e
+	mask = pipe->ring_size - 1;
cf3d8e
+	head = pipe->head;
cf3d8e
+	tail = pipe->tail;
cf3d8e
+
cf3d8e
+	n = pipe_occupancy(head, tail);
cf3d8e
+	if (nr_slots < n) {
cf3d8e
+		spin_unlock_irq(&pipe->rd_wait.lock);
cf3d8e
+		kfree(bufs);
cf3d8e
+		return -EBUSY;
cf3d8e
+	}
cf3d8e
+
cf3d8e
 	/*
cf3d8e
 	 * The pipe array wraps around, so just start the new one at zero
cf3d8e
 	 * and adjust the indices.
cf3d8e
@@ -1299,6 +1302,8 @@ int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
cf3d8e
 	pipe->tail = tail;
cf3d8e
 	pipe->head = head;
cf3d8e
 
cf3d8e
+	spin_unlock_irq(&pipe->rd_wait.lock);
cf3d8e
+
cf3d8e
 	/* This might have made more room for writers */
cf3d8e
 	wake_up_interruptible(&pipe->wr_wait);
cf3d8e
 	return 0;
cf3d8e
-- 
cf3d8e
2.39.0
cf3d8e
cf3d8e