Blame SOURCES/CVE-2022-2585.patch

1128b3
From 3b7e363b1d5f3ca329a7056b509a54d081923cd1 Mon Sep 17 00:00:00 2001
1128b3
From: Yannick Cote <ycote@redhat.com>
1128b3
Date: Thu, 13 Oct 2022 10:36:30 -0400
1128b3
Subject: [KPATCH 9.0] kpatch fixes for CVE-2022-2585
1128b3
1128b3
Kernels:
1128b3
5.14.0-70.13.1.el9_0
1128b3
5.14.0-70.17.1.el9_0
1128b3
5.14.0-70.22.1.el9_0
1128b3
5.14.0-70.26.1.el9_0
1128b3
1128b3
Changes since last build:
1128b3
arches: x86_64 ppc64le
1128b3
exec.o: changed function: begin_new_exec
1128b3
exit.o: changed function: do_exit
1128b3
posix-timers.o: new function: kpatch_cve_2022_2585_exit_itimers
1128b3
---------------------------
1128b3
1128b3
Modifications:
1128b3
- removed changes to .h files, for kpatch locality
1128b3
- redefine exit_itimers instead of changing it
1128b3
  (kpatch_cve_2022_2585_exit_itimers())
1128b3
- use kpatch defined exit_itimers() everywhere it's called in the kernel
1128b3
1128b3
commit 84013659b0e8a6965e79f1e7d6108aa2be2230ab
1128b3
Author: Wander Lairson Costa <wander@redhat.com>
1128b3
Date:   Thu Aug 25 09:27:13 2022 -0300
1128b3
1128b3
    fix race between exit_itimers() and /proc/pid/timers
1128b3
1128b3
    Bugzilla: https://bugzilla.redhat.com/2116967
1128b3
    CVE: CVE-2022-2585
1128b3
    Y-Commit: a532f4903a5d24d1e5e692628458d3a10184f615
1128b3
1128b3
    O-Bugzilla: https://bugzilla.redhat.com/2116968
1128b3
1128b3
    commit d5b36a4dbd06c5e8e36ca8ccc552f679069e2946
1128b3
    Author: Oleg Nesterov <oleg@redhat.com>
1128b3
    Date:   Mon Jul 11 18:16:25 2022 +0200
1128b3
1128b3
        fix race between exit_itimers() and /proc/pid/timers
1128b3
1128b3
        As Chris explains, the comment above exit_itimers() is not correct,
1128b3
        we can race with proc_timers_seq_ops. Change exit_itimers() to clear
1128b3
        signal->posix_timers with ->siglock held.
1128b3
1128b3
        Cc: <stable@vger.kernel.org>
1128b3
        Reported-by: chris@accessvector.net
1128b3
        Signed-off-by: Oleg Nesterov <oleg@redhat.com>
1128b3
        Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1128b3
1128b3
    Signed-off-by: Wander Lairson Costa <wander@redhat.com>
1128b3
    Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
1128b3
1128b3
commit d91003cca875f4b0ca290db6e686ee960125da3a
1128b3
Author: Wander Lairson Costa <wander@redhat.com>
1128b3
Date:   Thu Aug 25 09:27:22 2022 -0300
1128b3
1128b3
    posix-cpu-timers: Cleanup CPU timers before freeing them during exec
1128b3
1128b3
    Bugzilla: https://bugzilla.redhat.com/2116967
1128b3
    CVE: CVE-2022-2585
1128b3
    Y-Commit: b89dd8173ef086055a00bd606813e370efe7f0d7
1128b3
1128b3
    O-Bugzilla: https://bugzilla.redhat.com/2116968
1128b3
1128b3
    commit e362359ace6f87c201531872486ff295df306d13
1128b3
    Author: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
1128b3
    Date:   Tue Aug 9 14:07:51 2022 -0300
1128b3
1128b3
        posix-cpu-timers: Cleanup CPU timers before freeing them during exec
1128b3
1128b3
        Commit 55e8c8eb2c7b ("posix-cpu-timers: Store a reference to a pid not a
1128b3
        task") started looking up tasks by PID when deleting a CPU timer.
1128b3
1128b3
        When a non-leader thread calls execve, it will switch PIDs with the leader
1128b3
        process. Then, as it calls exit_itimers, posix_cpu_timer_del cannot find
1128b3
        the task because the timer still points out to the old PID.
1128b3
1128b3
        That means that armed timers won't be disarmed, that is, they won't be
1128b3
        removed from the timerqueue_list. exit_itimers will still release their
1128b3
        memory, and when that list is later processed, it leads to a
1128b3
        use-after-free.
1128b3
1128b3
        Clean up the timers from the de-threaded task before freeing them. This
1128b3
        prevents a reported use-after-free.
1128b3
1128b3
        Fixes: 55e8c8eb2c7b ("posix-cpu-timers: Store a reference to a pid not a task")
1128b3
        Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
1128b3
        Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
1128b3
        Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
1128b3
        Cc: <stable@vger.kernel.org>
1128b3
        Link: https://lore.kernel.org/r/20220809170751.164716-1-cascardo@canonical.com
1128b3
1128b3
    Signed-off-by: Wander Lairson Costa <wander@redhat.com>
1128b3
    Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
1128b3
1128b3
Signed-off-by: Yannick Cote <ycote@redhat.com>
1128b3
---
1128b3
 fs/exec.c                  |  6 +++++-
1128b3
 kernel/exit.c              |  4 +++-
1128b3
 kernel/time/posix-timers.c | 26 +++++++++++++++++++++++++-
1128b3
 3 files changed, 33 insertions(+), 3 deletions(-)
1128b3
1128b3
diff --git a/fs/exec.c b/fs/exec.c
1128b3
index 2bb8dd6a4e2a..decf9ccef49d 100644
1128b3
--- a/fs/exec.c
1128b3
+++ b/fs/exec.c
1128b3
@@ -1229,6 +1229,7 @@ void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec)
1128b3
 	perf_event_comm(tsk, exec);
1128b3
 }
1128b3
 
1128b3
+void kpatch_cve_2022_2585_exit_itimers(struct task_struct *tsk);
1128b3
 /*
1128b3
  * Calling this is the point of no return. None of the failures will be
1128b3
  * seen by userspace since either the process is already taking a fatal
1128b3
@@ -1292,7 +1293,10 @@ int begin_new_exec(struct linux_binprm * bprm)
1128b3
 	bprm->mm = NULL;
1128b3
 
1128b3
 #ifdef CONFIG_POSIX_TIMERS
1128b3
-	exit_itimers(me->signal);
1128b3
+	spin_lock_irq(&me->sighand->siglock);
1128b3
+	posix_cpu_timers_exit(me);
1128b3
+	spin_unlock_irq(&me->sighand->siglock);
1128b3
+	kpatch_cve_2022_2585_exit_itimers(me);
1128b3
 	flush_itimer_signals();
1128b3
 #endif
1128b3
 
1128b3
diff --git a/kernel/exit.c b/kernel/exit.c
1128b3
index 1731f60de259..d1e618505b7d 100644
1128b3
--- a/kernel/exit.c
1128b3
+++ b/kernel/exit.c
1128b3
@@ -725,6 +725,7 @@ static void check_stack_usage(void)
1128b3
 static inline void check_stack_usage(void) {}
1128b3
 #endif
1128b3
 
1128b3
+void kpatch_cve_2022_2585_exit_itimers(struct task_struct *tsk);
1128b3
 void __noreturn do_exit(long code)
1128b3
 {
1128b3
 	struct task_struct *tsk = current;
1128b3
@@ -797,7 +798,8 @@ void __noreturn do_exit(long code)
1128b3
 
1128b3
 #ifdef CONFIG_POSIX_TIMERS
1128b3
 		hrtimer_cancel(&tsk->signal->real_timer);
1128b3
-		exit_itimers(tsk->signal);
1128b3
+		kpatch_cve_2022_2585_exit_itimers(tsk);
1128b3
+
1128b3
 #endif
1128b3
 		if (tsk->mm)
1128b3
 			setmax_mm_hiwater_rss(&tsk->signal->maxrss, tsk->mm);
1128b3
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
1128b3
index 1cd10b102c51..8a1f61232282 100644
1128b3
--- a/kernel/time/posix-timers.c
1128b3
+++ b/kernel/time/posix-timers.c
1128b3
@@ -1035,7 +1035,7 @@ SYSCALL_DEFINE1(timer_delete, timer_t, timer_id)
1128b3
 /*
1128b3
  * return timer owned by the process, used by exit_itimers
1128b3
  */
1128b3
-static void itimer_delete(struct k_itimer *timer)
1128b3
+static __always_inline void itimer_delete(struct k_itimer *timer)
1128b3
 {
1128b3
 retry_delete:
1128b3
 	spin_lock_irq(&timer->it_lock);
1128b3
@@ -1050,6 +1050,30 @@ static void itimer_delete(struct k_itimer *timer)
1128b3
 	release_posix_timer(timer, IT_ID_SET);
1128b3
 }
1128b3
 
1128b3
+/*
1128b3
+ * CVE-2022-2585 - kpatch exit_itimers() redefinition
1128b3
+ * This is called by do_exit or de_thread, only when nobody else can
1128b3
+ * modify the signal->posix_timers list. Yet we need sighand->siglock
1128b3
+ * to prevent the race with /proc/pid/timers.
1128b3
+ */
1128b3
+void kpatch_cve_2022_2585_exit_itimers(struct task_struct *tsk)
1128b3
+{
1128b3
+	struct list_head timers;
1128b3
+	struct k_itimer *tmr;
1128b3
+
1128b3
+	if (list_empty(&tsk->signal->posix_timers))
1128b3
+		return;
1128b3
+
1128b3
+	spin_lock_irq(&tsk->sighand->siglock);
1128b3
+	list_replace_init(&tsk->signal->posix_timers, &timers);
1128b3
+	spin_unlock_irq(&tsk->sighand->siglock);
1128b3
+
1128b3
+	while (!list_empty(&timers)) {
1128b3
+		tmr = list_first_entry(&timers, struct k_itimer, list);
1128b3
+		itimer_delete(tmr);
1128b3
+	}
1128b3
+}
1128b3
+
1128b3
 /*
1128b3
  * This is called by do_exit or de_thread, only when there are no more
1128b3
  * references to the shared signal_struct.
1128b3
-- 
1128b3
2.37.3
1128b3