From: Greg Kroah-Hartman Date: Tue, 12 Nov 2024 08:38:12 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v5.15.172~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=74305fbac2f152757b3837300ff20be0d8d3aa56;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: ftrace-fix-possible-use-after-free-issue-in-ftrace_location.patch nfsd-fix-nfsv4-s-putpubfh-operation.patch --- diff --git a/queue-5.4/ftrace-fix-possible-use-after-free-issue-in-ftrace_location.patch b/queue-5.4/ftrace-fix-possible-use-after-free-issue-in-ftrace_location.patch new file mode 100644 index 00000000000..c73875cf5fe --- /dev/null +++ b/queue-5.4/ftrace-fix-possible-use-after-free-issue-in-ftrace_location.patch @@ -0,0 +1,150 @@ +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) +[Hagar: Modified to apply on v5.4.y] +Signed-off-by: Hagar Hemdan +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/ftrace.c | 30 +++++++++++++++++++++--------- + 1 file changed, 21 insertions(+), 9 deletions(-) + +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -1552,7 +1552,9 @@ unsigned long ftrace_location_range(unsi + struct ftrace_page *pg; + struct dyn_ftrace *rec; + struct dyn_ftrace key; ++ unsigned long ip = 0; + ++ rcu_read_lock(); + key.ip = start; + key.flags = end; /* overload flags, as it is unsigned long */ + +@@ -1565,10 +1567,13 @@ unsigned long ftrace_location_range(unsi + sizeof(struct dyn_ftrace), + ftrace_cmp_recs); + if (rec) +- return rec->ip; ++ { ++ ip = rec->ip; ++ break; ++ } + } +- +- return 0; ++ rcu_read_unlock(); ++ return ip; + } + + /** +@@ -5736,6 +5741,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; +@@ -5889,6 +5896,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 */ +@@ -6196,6 +6206,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; +@@ -6239,12 +6250,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; +@@ -6261,6 +6268,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-5.4/nfsd-fix-nfsv4-s-putpubfh-operation.patch b/queue-5.4/nfsd-fix-nfsv4-s-putpubfh-operation.patch new file mode 100644 index 00000000000..434cc966a93 --- /dev/null +++ b/queue-5.4/nfsd-fix-nfsv4-s-putpubfh-operation.patch @@ -0,0 +1,56 @@ +From 202f39039a11402dcbcd5fece8d9fa6be83f49ae Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Sun, 11 Aug 2024 13:11:07 -0400 +Subject: NFSD: Fix NFSv4's PUTPUBFH operation + +From: Chuck Lever + +commit 202f39039a11402dcbcd5fece8d9fa6be83f49ae upstream. + +According to RFC 8881, all minor versions of NFSv4 support PUTPUBFH. + +Replace the XDR decoder for PUTPUBFH with a "noop" since we no +longer want the minorversion check, and PUTPUBFH has no arguments to +decode. (Ideally nfsd4_decode_noop should really be called +nfsd4_decode_void). + +PUTPUBFH should now behave just like PUTROOTFH. + +Reported-by: Cedric Blancher +Fixes: e1a90ebd8b23 ("NFSD: Combine decode operations for v4 and v4.1") +Cc: Dan Shelton +Cc: Roland Mainz +Cc: stable@vger.kernel.org +[ cel: adjusted to apply to origin/linux-5.4.y ] +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4xdr.c | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -1069,14 +1069,6 @@ nfsd4_decode_putfh(struct nfsd4_compound + } + + static __be32 +-nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p) +-{ +- if (argp->minorversion == 0) +- return nfs_ok; +- return nfserr_notsupp; +-} +- +-static __be32 + nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) + { + DECODE_HEAD; +@@ -1825,7 +1817,7 @@ static const nfsd4_dec nfsd4_dec_ops[] = + [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm, + [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade, + [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh, +- [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_putpubfh, ++ [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_noop, + [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop, + [OP_READ] = (nfsd4_dec)nfsd4_decode_read, + [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir, diff --git a/queue-5.4/series b/queue-5.4/series index dd63313a032..4f36bbc19ce 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -46,3 +46,5 @@ irqchip-gic-v3-force-propagation-of-the-active-state-with-a-read-back.patch ocfs2-remove-entry-once-instead-of-null-ptr-dereference-in-ocfs2_xa_remove.patch alsa-usb-audio-support-jack-detection-on-dell-dock.patch alsa-usb-audio-add-quirks-for-dell-wd19-dock.patch +nfsd-fix-nfsv4-s-putpubfh-operation.patch +ftrace-fix-possible-use-after-free-issue-in-ftrace_location.patch