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