Blame SOURCES/CVE-2020-0466.patch

c6ac4c
From c17b58ebffbfa862b3f1815e208db340bd1664eb Mon Sep 17 00:00:00 2001
c6ac4c
From: Yannick Cote <ycote@redhat.com>
c6ac4c
Date: Tue, 1 Feb 2022 14:14:41 -0500
c6ac4c
Subject: [KPATCH CVE-2020-0466] epoll: kpatch fixes for CVE-2020-0466
c6ac4c
c6ac4c
Kernels:
c6ac4c
3.10.0-1160.15.2.el7
c6ac4c
3.10.0-1160.21.1.el7
c6ac4c
3.10.0-1160.24.1.el7
c6ac4c
3.10.0-1160.25.1.el7
c6ac4c
3.10.0-1160.31.1.el7
c6ac4c
3.10.0-1160.36.2.el7
c6ac4c
3.10.0-1160.41.1.el7
c6ac4c
3.10.0-1160.42.2.el7
c6ac4c
3.10.0-1160.45.1.el7
c6ac4c
3.10.0-1160.49.1.el7
c6ac4c
3.10.0-1160.53.1.el7
c6ac4c
c6ac4c
Changes since last build:
c6ac4c
[x86_64]:
c6ac4c
eventpoll.o: changed function: SyS_epoll_ctl
c6ac4c
eventpoll.o: changed function: clear_tfile_check_list
c6ac4c
eventpoll.o: changed function: ep_loop_check_proc
c6ac4c
c6ac4c
[ppc64le]:
c6ac4c
eventpoll.o: changed function: SyS_epoll_ctl
c6ac4c
eventpoll.o: changed function: ep_loop_check_proc
c6ac4c
c6ac4c
---------------------------
c6ac4c
c6ac4c
Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-7/-/merge_requests/22
c6ac4c
Approved-by: Artem Savkov (@artem.savkov)
c6ac4c
Kernels:
c6ac4c
3.10.0-1160.21.1.el7
c6ac4c
3.10.0-1160.24.1.el7
c6ac4c
3.10.0-1160.25.1.el7
c6ac4c
3.10.0-1160.31.1.el7
c6ac4c
3.10.0-1160.36.2.el7
c6ac4c
3.10.0-1160.41.1.el7
c6ac4c
3.10.0-1160.42.2.el7
c6ac4c
3.10.0-1160.45.1.el7
c6ac4c
3.10.0-1160.49.1.el7
c6ac4c
3.10.0-1160.53.1.el7
c6ac4c
c6ac4c
Modifications: none
c6ac4c
c6ac4c
commit f771ed0537c55c506dc846cb8f3da60f6383a2b3
c6ac4c
Author: Carlos Maiolino <cmaiolino@redhat.com>
c6ac4c
Date:   Sat Dec 18 09:23:31 2021 +0100
c6ac4c
c6ac4c
    epoll: Keep a reference on files added to the check list
c6ac4c
c6ac4c
    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2042760
c6ac4c
    Tested: Sanity check only
c6ac4c
    CVE: CVE-2020-0466
c6ac4c
c6ac4c
    Conflicts:
c6ac4c
            - RHEL7 has no support for non-blocking do_epoll_ctl(), so the
c6ac4c
              original patch got this part stripped.
c6ac4c
c6ac4c
    When adding a new fd to an epoll, and that this new fd is an
c6ac4c
    epoll fd itself, we recursively scan the fds attached to it
c6ac4c
    to detect cycles, and add non-epool files to a "check list"
c6ac4c
    that gets subsequently parsed.
c6ac4c
c6ac4c
    However, this check list isn't completely safe when deletions
c6ac4c
    can happen concurrently. To sidestep the issue, make sure that
c6ac4c
    a struct file placed on the check list sees its f_count increased,
c6ac4c
    ensuring that a concurrent deletion won't result in the file
c6ac4c
    disapearing from under our feet.
c6ac4c
c6ac4c
    Cc: stable@vger.kernel.org
c6ac4c
    Signed-off-by: Marc Zyngier <maz@kernel.org>
c6ac4c
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
c6ac4c
    (cherry picked from commit a9ed4a6560b8562b7e2e2bed9527e88001f7b682)
c6ac4c
c6ac4c
    Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
c6ac4c
c6ac4c
commit 0875a380011a7ff7f4504b72890c29fec420d1cd
c6ac4c
Author: Carlos Maiolino <cmaiolino@redhat.com>
c6ac4c
Date:   Sat Dec 18 09:23:47 2021 +0100
c6ac4c
c6ac4c
    fix regression in "epoll: Keep a reference on files added to the check list"
c6ac4c
c6ac4c
    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2042760
c6ac4c
    Tested: Sanity check only
c6ac4c
    CVE: CVE-2020-0466
c6ac4c
c6ac4c
    epoll_loop_check_proc() can run into a file already committed to destruction;
c6ac4c
    we can't grab a reference on those and don't need to add them to the set for
c6ac4c
    reverse path check anyway.
c6ac4c
c6ac4c
    Tested-by: Marc Zyngier <maz@kernel.org>
c6ac4c
    Fixes: a9ed4a6560b8 ("epoll: Keep a reference on files added to the check list")
c6ac4c
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
c6ac4c
    (cherry picked from commit 77f4689de17c0887775bb77896f4cc11a39bf848)
c6ac4c
c6ac4c
    Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
c6ac4c
c6ac4c
Signed-off-by: Yannick Cote <ycote@redhat.com>
c6ac4c
---
c6ac4c
 fs/eventpoll.c | 13 +++++++++----
c6ac4c
 1 file changed, 9 insertions(+), 4 deletions(-)
c6ac4c
c6ac4c
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
c6ac4c
index 6731b99a481f..ca0eb701eeb4 100644
c6ac4c
--- a/fs/eventpoll.c
c6ac4c
+++ b/fs/eventpoll.c
c6ac4c
@@ -1750,9 +1750,11 @@ static int ep_loop_check_proc(void *priv, void *cookie, int call_nests)
c6ac4c
 			 * not already there, and calling reverse_path_check()
c6ac4c
 			 * during ep_insert().
c6ac4c
 			 */
c6ac4c
-			if (list_empty(&epi->ffd.file->f_tfile_llink))
c6ac4c
-				list_add(&epi->ffd.file->f_tfile_llink,
c6ac4c
-					 &tfile_check_list);
c6ac4c
+			if (list_empty(&epi->ffd.file->f_tfile_llink)) {
c6ac4c
+				if (get_file_rcu(epi->ffd.file))
c6ac4c
+					list_add(&epi->ffd.file->f_tfile_llink,
c6ac4c
+						 &tfile_check_list);
c6ac4c
+			}
c6ac4c
 		}
c6ac4c
 	}
c6ac4c
 	mutex_unlock(&ep->mtx);
c6ac4c
@@ -1796,6 +1798,7 @@ static void clear_tfile_check_list(void)
c6ac4c
 		file = list_first_entry(&tfile_check_list, struct file,
c6ac4c
 					f_tfile_llink);
c6ac4c
 		list_del_init(&file->f_tfile_llink);
c6ac4c
+		fput(file);
c6ac4c
 	}
c6ac4c
 	INIT_LIST_HEAD(&tfile_check_list);
c6ac4c
 }
c6ac4c
@@ -1951,9 +1954,11 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
c6ac4c
 					clear_tfile_check_list();
c6ac4c
 					goto error_tgt_fput;
c6ac4c
 				}
c6ac4c
-			} else
c6ac4c
+			} else {
c6ac4c
+				get_file(tf.file);
c6ac4c
 				list_add(&tf.file->f_tfile_llink,
c6ac4c
 							&tfile_check_list);
c6ac4c
+			}
c6ac4c
 			mutex_lock_nested(&ep->mtx, 0);
c6ac4c
 			if (is_file_epoll(tf.file)) {
c6ac4c
 				tep = tf.file->private_data;
c6ac4c
-- 
c6ac4c
2.26.3
c6ac4c
c6ac4c