Blame SOURCES/CVE-2020-0466.patch

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