From 7b410358efd0b6f926eae8764476666f692ce77d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 27 May 2024 20:19:17 +0200 Subject: [PATCH] 6.9-stable patches added patches: ftrace-fix-possible-use-after-free-issue-in-ftrace_location.patch selftests-ftrace-fix-btfarg-testcase-to-check-fprobe-is-enabled-correctly.patch selftests-ftrace-fix-checkbashisms-errors.patch x86-tsc-trust-initial-offset-in-architectural-tsc-adjust-msrs.patch --- ...-after-free-issue-in-ftrace_location.patch | 170 ++++++++++++++++++ ...to-check-fprobe-is-enabled-correctly.patch | 34 ++++ ...ests-ftrace-fix-checkbashisms-errors.patch | 56 ++++++ queue-6.9/series | 4 + ...set-in-architectural-tsc-adjust-msrs.patch | 46 +++++ 5 files changed, 310 insertions(+) create mode 100644 queue-6.9/ftrace-fix-possible-use-after-free-issue-in-ftrace_location.patch create mode 100644 queue-6.9/selftests-ftrace-fix-btfarg-testcase-to-check-fprobe-is-enabled-correctly.patch create mode 100644 queue-6.9/selftests-ftrace-fix-checkbashisms-errors.patch create mode 100644 queue-6.9/x86-tsc-trust-initial-offset-in-architectural-tsc-adjust-msrs.patch diff --git a/queue-6.9/ftrace-fix-possible-use-after-free-issue-in-ftrace_location.patch b/queue-6.9/ftrace-fix-possible-use-after-free-issue-in-ftrace_location.patch new file mode 100644 index 00000000000..63d953c6cf0 --- /dev/null +++ b/queue-6.9/ftrace-fix-possible-use-after-free-issue-in-ftrace_location.patch @@ -0,0 +1,170 @@ +From e60b613df8b6253def41215402f72986fee3fc8d Mon Sep 17 00:00:00 2001 +From: Zheng Yejian +Date: Fri, 10 May 2024 03:28:59 +0800 +Subject: ftrace: Fix possible use-after-free issue in ftrace_location() + +From: Zheng Yejian + +commit e60b613df8b6253def41215402f72986fee3fc8d upstream. + +KASAN reports a bug: + + BUG: KASAN: use-after-free in ftrace_location+0x90/0x120 + Read of size 8 at addr ffff888141d40010 by task insmod/424 + CPU: 8 PID: 424 Comm: insmod Tainted: G W 6.9.0-rc2+ + [...] + Call Trace: + + dump_stack_lvl+0x68/0xa0 + print_report+0xcf/0x610 + kasan_report+0xb5/0xe0 + ftrace_location+0x90/0x120 + register_kprobe+0x14b/0xa40 + kprobe_init+0x2d/0xff0 [kprobe_example] + do_one_initcall+0x8f/0x2d0 + do_init_module+0x13a/0x3c0 + load_module+0x3082/0x33d0 + init_module_from_file+0xd2/0x130 + __x64_sys_finit_module+0x306/0x440 + do_syscall_64+0x68/0x140 + entry_SYSCALL_64_after_hwframe+0x71/0x79 + +The root cause is that, in lookup_rec(), ftrace record of some address +is being searched in ftrace pages of some module, but those ftrace pages +at the same time is being freed in ftrace_release_mod() as the +corresponding module is being deleted: + + CPU1 | CPU2 + register_kprobes() { | delete_module() { + check_kprobe_address_safe() { | + arch_check_ftrace_location() { | + ftrace_location() { | + lookup_rec() // USE! | ftrace_release_mod() // Free! + +To fix this issue: + 1. Hold rcu lock as accessing ftrace pages in ftrace_location_range(); + 2. Use ftrace_location_range() instead of lookup_rec() in + ftrace_location(); + 3. Call synchronize_rcu() before freeing any ftrace pages both in + ftrace_process_locs()/ftrace_release_mod()/ftrace_free_mem(). + +Link: https://lore.kernel.org/linux-trace-kernel/20240509192859.1273558-1-zhengyejian1@huawei.com + +Cc: stable@vger.kernel.org +Cc: +Cc: +Cc: +Fixes: ae6aa16fdc16 ("kprobes: introduce ftrace based optimization") +Suggested-by: Steven Rostedt +Signed-off-by: Zheng Yejian +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/ftrace.c | 39 +++++++++++++++++++++++---------------- + 1 file changed, 23 insertions(+), 16 deletions(-) + +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -1595,12 +1595,15 @@ static struct dyn_ftrace *lookup_rec(uns + unsigned long ftrace_location_range(unsigned long start, unsigned long end) + { + struct dyn_ftrace *rec; ++ unsigned long ip = 0; + ++ rcu_read_lock(); + rec = lookup_rec(start, end); + if (rec) +- return rec->ip; ++ ip = rec->ip; ++ rcu_read_unlock(); + +- return 0; ++ return ip; + } + + /** +@@ -1614,25 +1617,22 @@ unsigned long ftrace_location_range(unsi + */ + unsigned long ftrace_location(unsigned long ip) + { +- struct dyn_ftrace *rec; ++ unsigned long loc; + unsigned long offset; + unsigned long size; + +- rec = lookup_rec(ip, ip); +- if (!rec) { ++ loc = ftrace_location_range(ip, ip); ++ if (!loc) { + if (!kallsyms_lookup_size_offset(ip, &size, &offset)) + goto out; + + /* map sym+0 to __fentry__ */ + if (!offset) +- rec = lookup_rec(ip, ip + size - 1); ++ loc = ftrace_location_range(ip, ip + size - 1); + } + +- if (rec) +- return rec->ip; +- + out: +- return 0; ++ return loc; + } + + /** +@@ -6596,6 +6596,8 @@ static int ftrace_process_locs(struct mo + /* We should have used all pages unless we skipped some */ + if (pg_unuse) { + WARN_ON(!skipped); ++ /* Need to synchronize with ftrace_location_range() */ ++ synchronize_rcu(); + ftrace_free_pages(pg_unuse); + } + return ret; +@@ -6809,6 +6811,9 @@ void ftrace_release_mod(struct module *m + out_unlock: + mutex_unlock(&ftrace_lock); + ++ /* Need to synchronize with ftrace_location_range() */ ++ if (tmp_page) ++ synchronize_rcu(); + for (pg = tmp_page; pg; pg = tmp_page) { + + /* Needs to be called outside of ftrace_lock */ +@@ -7142,6 +7147,7 @@ void ftrace_free_mem(struct module *mod, + unsigned long start = (unsigned long)(start_ptr); + unsigned long end = (unsigned long)(end_ptr); + struct ftrace_page **last_pg = &ftrace_pages_start; ++ struct ftrace_page *tmp_page = NULL; + struct ftrace_page *pg; + struct dyn_ftrace *rec; + struct dyn_ftrace key; +@@ -7183,12 +7189,8 @@ void ftrace_free_mem(struct module *mod, + ftrace_update_tot_cnt--; + if (!pg->index) { + *last_pg = pg->next; +- if (pg->records) { +- free_pages((unsigned long)pg->records, pg->order); +- ftrace_number_of_pages -= 1 << pg->order; +- } +- ftrace_number_of_groups--; +- kfree(pg); ++ pg->next = tmp_page; ++ tmp_page = pg; + pg = container_of(last_pg, struct ftrace_page, next); + if (!(*last_pg)) + ftrace_pages = pg; +@@ -7205,6 +7207,11 @@ void ftrace_free_mem(struct module *mod, + clear_func_from_hashes(func); + kfree(func); + } ++ /* Need to synchronize with ftrace_location_range() */ ++ if (tmp_page) { ++ synchronize_rcu(); ++ ftrace_free_pages(tmp_page); ++ } + } + + void __init ftrace_free_init_mem(void) diff --git a/queue-6.9/selftests-ftrace-fix-btfarg-testcase-to-check-fprobe-is-enabled-correctly.patch b/queue-6.9/selftests-ftrace-fix-btfarg-testcase-to-check-fprobe-is-enabled-correctly.patch new file mode 100644 index 00000000000..0f240a12a5f --- /dev/null +++ b/queue-6.9/selftests-ftrace-fix-btfarg-testcase-to-check-fprobe-is-enabled-correctly.patch @@ -0,0 +1,34 @@ +From 2fd3ef1b9265eda7f53b9506f1ebfb67eb6435a2 Mon Sep 17 00:00:00 2001 +From: "Masami Hiramatsu (Google)" +Date: Sat, 4 May 2024 09:33:10 +0900 +Subject: selftests/ftrace: Fix BTFARG testcase to check fprobe is enabled correctly + +From: Masami Hiramatsu (Google) + +commit 2fd3ef1b9265eda7f53b9506f1ebfb67eb6435a2 upstream. + +Since the dynevent/add_remove_btfarg.tc test case forgets to ensure that +fprobe is enabled for some structure field access tests which uses the +fprobe, it fails if CONFIG_FPROBE=n or CONFIG_FPROBE_EVENTS=n. +Fixes it to ensure the fprobe events are supported. + +Fixes: d892d3d3d885 ("selftests/ftrace: Add BTF fields access testcases") +Cc: stable@vger.kernel.org +Signed-off-by: Masami Hiramatsu (Google) +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/ftrace/test.d/dynevent/add_remove_btfarg.tc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_btfarg.tc ++++ b/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_btfarg.tc +@@ -53,7 +53,7 @@ fi + + echo > dynamic_events + +-if [ "$FIELDS" ] ; then ++if [ "$FIELDS" -a "$FPROBES" ] ; then + echo "t:tpevent ${TP2} obj_size=s->object_size" >> dynamic_events + echo "f:fpevent ${TP3}%return path=\$retval->name:string" >> dynamic_events + echo "t:tpevent2 ${TP4} p->se.group_node.next->prev" >> dynamic_events diff --git a/queue-6.9/selftests-ftrace-fix-checkbashisms-errors.patch b/queue-6.9/selftests-ftrace-fix-checkbashisms-errors.patch new file mode 100644 index 00000000000..db744dfdd8c --- /dev/null +++ b/queue-6.9/selftests-ftrace-fix-checkbashisms-errors.patch @@ -0,0 +1,56 @@ +From b07b7e2fd51840c7dfffa98c4344ab36195bb8dc Mon Sep 17 00:00:00 2001 +From: "Masami Hiramatsu (Google)" +Date: Sat, 4 May 2024 09:33:19 +0900 +Subject: selftests/ftrace: Fix checkbashisms errors + +From: Masami Hiramatsu (Google) + +commit b07b7e2fd51840c7dfffa98c4344ab36195bb8dc upstream. + +Fix the below checkbashisms errors. Because of these errors, these tests +will fail on dash shell. + +possible bashism in test.d/kprobe/kretprobe_entry_arg.tc line 14 ('function' is useless): +function streq() { +possible bashism in test.d/dynevent/fprobe_entry_arg.tc line 14 ('function' is useless): +function streq() { + +Fixes: f6e2253a617c ("selftests/ftrace: Add test cases for entry args at function exit") +Cc: stable@vger.kernel.org +Signed-off-by: Masami Hiramatsu (Google) +Signed-off-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman +--- + .../selftests/ftrace/test.d/dynevent/fprobe_entry_arg.tc | 2 +- + .../selftests/ftrace/test.d/kprobe/kretprobe_entry_arg.tc | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_entry_arg.tc b/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_entry_arg.tc +index d183b8a8ecf8..1e251ce2998e 100644 +--- a/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_entry_arg.tc ++++ b/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_entry_arg.tc +@@ -11,7 +11,7 @@ echo 1 > events/tests/enable + echo > trace + cat trace > /dev/null + +-function streq() { ++streq() { + test $1 = $2 + } + +diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_entry_arg.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_entry_arg.tc +index 53b82f36a1d0..e50470b53164 100644 +--- a/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_entry_arg.tc ++++ b/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_entry_arg.tc +@@ -11,7 +11,7 @@ echo 1 > events/kprobes/enable + echo > trace + cat trace > /dev/null + +-function streq() { ++streq() { + test $1 = $2 + } + +-- +2.45.1 + diff --git a/queue-6.9/series b/queue-6.9/series index 4850bb5a26f..ac71037d3d7 100644 --- a/queue-6.9/series +++ b/queue-6.9/series @@ -1,3 +1,7 @@ +x86-tsc-trust-initial-offset-in-architectural-tsc-adjust-msrs.patch +selftests-ftrace-fix-btfarg-testcase-to-check-fprobe-is-enabled-correctly.patch +selftests-ftrace-fix-checkbashisms-errors.patch +ftrace-fix-possible-use-after-free-issue-in-ftrace_location.patch revert-arm64-fpsimd-implement-lazy-restore-for-kernel-mode-fpsimd.patch arm64-fpsimd-avoid-erroneous-elide-of-user-state-reload.patch reapply-arm64-fpsimd-implement-lazy-restore-for-kernel-mode-fpsimd.patch diff --git a/queue-6.9/x86-tsc-trust-initial-offset-in-architectural-tsc-adjust-msrs.patch b/queue-6.9/x86-tsc-trust-initial-offset-in-architectural-tsc-adjust-msrs.patch new file mode 100644 index 00000000000..47cc9bf5dc8 --- /dev/null +++ b/queue-6.9/x86-tsc-trust-initial-offset-in-architectural-tsc-adjust-msrs.patch @@ -0,0 +1,46 @@ +From 455f9075f14484f358b3c1d6845b4a438de198a7 Mon Sep 17 00:00:00 2001 +From: Daniel J Blueman +Date: Fri, 19 Apr 2024 16:51:46 +0800 +Subject: x86/tsc: Trust initial offset in architectural TSC-adjust MSRs + +From: Daniel J Blueman + +commit 455f9075f14484f358b3c1d6845b4a438de198a7 upstream. + +When the BIOS configures the architectural TSC-adjust MSRs on secondary +sockets to correct a constant inter-chassis offset, after Linux brings the +cores online, the TSC sync check later resets the core-local MSR to 0, +triggering HPET fallback and leading to performance loss. + +Fix this by unconditionally using the initial adjust values read from the +MSRs. Trusting the initial offsets in this architectural mechanism is a +better approach than special-casing workarounds for specific platforms. + +Signed-off-by: Daniel J Blueman +Signed-off-by: Thomas Gleixner +Reviewed-by: Steffen Persvold +Reviewed-by: James Cleverdon +Reviewed-by: Dimitri Sivanich +Reviewed-by: Prarit Bhargava +Link: https://lore.kernel.org/r/20240419085146.175665-1-daniel@quora.org +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/tsc_sync.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/arch/x86/kernel/tsc_sync.c ++++ b/arch/x86/kernel/tsc_sync.c +@@ -193,11 +193,9 @@ bool tsc_store_and_check_tsc_adjust(bool + cur->warned = false; + + /* +- * If a non-zero TSC value for socket 0 may be valid then the default +- * adjusted value cannot assumed to be zero either. ++ * The default adjust value cannot be assumed to be zero on any socket. + */ +- if (tsc_async_resets) +- cur->adjusted = bootval; ++ cur->adjusted = bootval; + + /* + * Check whether this CPU is the first in a package to come up. In -- 2.47.3