From: Sasha Levin Date: Sat, 9 Dec 2023 11:50:52 +0000 (-0500) Subject: Fixes for 5.15 X-Git-Tag: v6.6.6~18 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b7c0cafb3dd7d6a0101b1beeec66bedeb170723e;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/binder-fix-memory-leaks-of-spam-and-pending-work.patch b/queue-5.15/binder-fix-memory-leaks-of-spam-and-pending-work.patch new file mode 100644 index 00000000000..85e1583cd72 --- /dev/null +++ b/queue-5.15/binder-fix-memory-leaks-of-spam-and-pending-work.patch @@ -0,0 +1,77 @@ +From 16f80599a2c254be8e6b4fe711280a7c9a0601ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Dec 2023 03:48:42 +0000 +Subject: binder: fix memory leaks of spam and pending work + +From: Carlos Llamas + +commit 1aa3aaf8953c84bad398adf6c3cabc9d6685bf7d upstream + +A transaction complete work is allocated and queued for each +transaction. Under certain conditions the work->type might be marked as +BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT to notify userspace about +potential spamming threads or as BINDER_WORK_TRANSACTION_PENDING when +the target is currently frozen. + +However, these work types are not being handled in binder_release_work() +so they will leak during a cleanup. This was reported by syzkaller with +the following kmemleak dump: + +BUG: memory leak +unreferenced object 0xffff88810e2d6de0 (size 32): + comm "syz-executor338", pid 5046, jiffies 4294968230 (age 13.590s) + hex dump (first 32 bytes): + e0 6d 2d 0e 81 88 ff ff e0 6d 2d 0e 81 88 ff ff .m-......m-..... + 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [] kmalloc_trace+0x25/0x90 mm/slab_common.c:1114 + [] kmalloc include/linux/slab.h:599 [inline] + [] kzalloc include/linux/slab.h:720 [inline] + [] binder_transaction+0x573/0x4050 drivers/android/binder.c:3152 + [] binder_thread_write+0x6b5/0x1860 drivers/android/binder.c:4010 + [] binder_ioctl_write_read drivers/android/binder.c:5066 [inline] + [] binder_ioctl+0x1b2c/0x3cf0 drivers/android/binder.c:5352 + [] vfs_ioctl fs/ioctl.c:51 [inline] + [] __do_sys_ioctl fs/ioctl.c:871 [inline] + [] __se_sys_ioctl fs/ioctl.c:857 [inline] + [] __x64_sys_ioctl+0xf2/0x140 fs/ioctl.c:857 + [] do_syscall_x64 arch/x86/entry/common.c:50 [inline] + [] do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80 + [] entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Fix the leaks by kfreeing these work types in binder_release_work() and +handle them as a BINDER_WORK_TRANSACTION_COMPLETE cleanup. + +Cc: stable@vger.kernel.org +Fixes: a7dc1e6f99df ("binder: tell userspace to dump current backtrace when detected oneway spamming") +Reported-by: syzbot+7f10c1653e35933c0f1e@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=7f10c1653e35933c0f1e +Suggested-by: Alice Ryhl +Signed-off-by: Carlos Llamas +Reviewed-by: Alice Ryhl +Acked-by: Todd Kjos +Link: https://lore.kernel.org/r/20230922175138.230331-1-cmllamas@google.com +Signed-off-by: Greg Kroah-Hartman +[cmllamas: backport to v5.15 by dropping BINDER_WORK_TRANSACTION_PENDING + as commit 0567461a7a6e is not present. Remove fixes tag accordingly.] +Signed-off-by: Carlos Llamas +Signed-off-by: Sasha Levin +--- + drivers/android/binder.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index cbbed43baf056..b63322e7e1011 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -4620,6 +4620,7 @@ static void binder_release_work(struct binder_proc *proc, + "undelivered TRANSACTION_ERROR: %u\n", + e->cmd); + } break; ++ case BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT: + case BINDER_WORK_TRANSACTION_COMPLETE: { + binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, + "undelivered TRANSACTION_COMPLETE\n"); +-- +2.42.0 + diff --git a/queue-5.15/kallsyms-make-kallsyms_on_each_symbol-generally-avai.patch b/queue-5.15/kallsyms-make-kallsyms_on_each_symbol-generally-avai.patch new file mode 100644 index 00000000000..ebc220f5c51 --- /dev/null +++ b/queue-5.15/kallsyms-make-kallsyms_on_each_symbol-generally-avai.patch @@ -0,0 +1,78 @@ +From 98aa2db59a072b52be5a8ec70c78e4dc632c031e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 May 2022 14:26:12 +0200 +Subject: kallsyms: Make kallsyms_on_each_symbol generally available + +From: Jiri Olsa + +[ Upstream commit d721def7392a7348ffb9f3583b264239cbd3702c ] + +Making kallsyms_on_each_symbol generally available, so it can be +used outside CONFIG_LIVEPATCH option in following changes. + +Rather than adding another ifdef option let's make the function +generally available (when CONFIG_KALLSYMS option is defined). + +Cc: Christoph Hellwig +Reviewed-by: Masami Hiramatsu +Signed-off-by: Jiri Olsa +Link: https://lore.kernel.org/r/20220510122616.2652285-2-jolsa@kernel.org +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + include/linux/kallsyms.h | 7 ++++++- + kernel/kallsyms.c | 2 -- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h +index a1d6fc82d7f06..eae9f423bd648 100644 +--- a/include/linux/kallsyms.h ++++ b/include/linux/kallsyms.h +@@ -74,11 +74,11 @@ static inline void *dereference_symbol_descriptor(void *ptr) + return ptr; + } + ++#ifdef CONFIG_KALLSYMS + int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, + unsigned long), + void *data); + +-#ifdef CONFIG_KALLSYMS + /* Lookup the address for a symbol. Returns 0 if not found. */ + unsigned long kallsyms_lookup_name(const char *name); + +@@ -172,6 +172,11 @@ static inline bool kallsyms_show_value(const struct cred *cred) + return false; + } + ++static inline int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, ++ unsigned long), void *data) ++{ ++ return -EOPNOTSUPP; ++} + #endif /*CONFIG_KALLSYMS*/ + + static inline void print_ip_sym(const char *loglvl, unsigned long ip) +diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c +index 0ba87982d017f..e0d9f77cf2d4b 100644 +--- a/kernel/kallsyms.c ++++ b/kernel/kallsyms.c +@@ -204,7 +204,6 @@ unsigned long kallsyms_lookup_name(const char *name) + return module_kallsyms_lookup_name(name); + } + +-#ifdef CONFIG_LIVEPATCH + /* + * Iterate over all symbols in vmlinux. For symbols from modules use + * module_kallsyms_on_each_symbol instead. +@@ -226,7 +225,6 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, + } + return 0; + } +-#endif /* CONFIG_LIVEPATCH */ + + static unsigned long get_symbol_pos(unsigned long addr, + unsigned long *symbolsize, +-- +2.42.0 + diff --git a/queue-5.15/series b/queue-5.15/series index 4a97dd0f52e..764b9ec1480 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -95,3 +95,6 @@ arm64-dts-mediatek-mt7622-fix-memory-node-warning-check.patch arm64-dts-mediatek-mt8183-kukui-jacuzzi-fix-dsi-unnecessary-cells-properties.patch arm64-dts-mediatek-mt8173-evb-fix-regulator-fixed-node-names.patch arm64-dts-mediatek-mt8183-fix-unit-address-for-scp-reserved-memory.patch +binder-fix-memory-leaks-of-spam-and-pending-work.patch +kallsyms-make-kallsyms_on_each_symbol-generally-avai.patch +tracing-kprobes-return-eaddrnotavail-when-func-match.patch diff --git a/queue-5.15/tracing-kprobes-return-eaddrnotavail-when-func-match.patch b/queue-5.15/tracing-kprobes-return-eaddrnotavail-when-func-match.patch new file mode 100644 index 00000000000..5f954d2cd8c --- /dev/null +++ b/queue-5.15/tracing-kprobes-return-eaddrnotavail-when-func-match.patch @@ -0,0 +1,146 @@ +From 164d8ddbfff70475e9b3a87099a15ad04c97718d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 13:42:49 +0300 +Subject: tracing/kprobes: Return EADDRNOTAVAIL when func matches several + symbols + +From: Francis Laniel + +[ Upstream commit b022f0c7e404887a7c5229788fc99eff9f9a80d5 ] + +When a kprobe is attached to a function that's name is not unique (is +static and shares the name with other functions in the kernel), the +kprobe is attached to the first function it finds. This is a bug as the +function that it is attaching to is not necessarily the one that the +user wants to attach to. + +Instead of blindly picking a function to attach to what is ambiguous, +error with EADDRNOTAVAIL to let the user know that this function is not +unique, and that the user must use another unique function with an +address offset to get to the function they want to attach to. + +Link: https://lore.kernel.org/all/20231020104250.9537-2-flaniel@linux.microsoft.com/ + +Cc: stable@vger.kernel.org +Fixes: 413d37d1eb69 ("tracing: Add kprobe-based event tracer") +Suggested-by: Masami Hiramatsu +Signed-off-by: Francis Laniel +Link: https://lore.kernel.org/lkml/20230819101105.b0c104ae4494a7d1f2eea742@kernel.org/ +Acked-by: Masami Hiramatsu (Google) +Signed-off-by: Masami Hiramatsu (Google) +Signed-off-by: Sasha Levin +--- + kernel/trace/trace_kprobe.c | 63 +++++++++++++++++++++++++++++++++++++ + kernel/trace/trace_probe.h | 1 + + 2 files changed, 64 insertions(+) + +diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c +index 0b3ee4eea51bf..c686b2dd35934 100644 +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -708,6 +708,25 @@ static struct notifier_block trace_kprobe_module_nb = { + .priority = 1 /* Invoked after kprobe module callback */ + }; + ++static int count_symbols(void *data, unsigned long unused) ++{ ++ unsigned int *count = data; ++ ++ (*count)++; ++ ++ return 0; ++} ++ ++static unsigned int number_of_same_symbols(char *func_name) ++{ ++ unsigned int count; ++ ++ count = 0; ++ kallsyms_on_each_match_symbol(count_symbols, func_name, &count); ++ ++ return count; ++} ++ + static int __trace_kprobe_create(int argc, const char *argv[]) + { + /* +@@ -836,6 +855,31 @@ static int __trace_kprobe_create(int argc, const char *argv[]) + } + } + ++ if (symbol && !strchr(symbol, ':')) { ++ unsigned int count; ++ ++ count = number_of_same_symbols(symbol); ++ if (count > 1) { ++ /* ++ * Users should use ADDR to remove the ambiguity of ++ * using KSYM only. ++ */ ++ trace_probe_log_err(0, NON_UNIQ_SYMBOL); ++ ret = -EADDRNOTAVAIL; ++ ++ goto error; ++ } else if (count == 0) { ++ /* ++ * We can return ENOENT earlier than when register the ++ * kprobe. ++ */ ++ trace_probe_log_err(0, BAD_PROBE_ADDR); ++ ret = -ENOENT; ++ ++ goto error; ++ } ++ } ++ + trace_probe_log_set_index(0); + if (event) { + ret = traceprobe_parse_event_name(&event, &group, buf, +@@ -1755,6 +1799,7 @@ static int unregister_kprobe_event(struct trace_kprobe *tk) + } + + #ifdef CONFIG_PERF_EVENTS ++ + /* create a trace_kprobe, but don't add it to global lists */ + struct trace_event_call * + create_local_trace_kprobe(char *func, void *addr, unsigned long offs, +@@ -1765,6 +1810,24 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs, + int ret; + char *event; + ++ if (func) { ++ unsigned int count; ++ ++ count = number_of_same_symbols(func); ++ if (count > 1) ++ /* ++ * Users should use addr to remove the ambiguity of ++ * using func only. ++ */ ++ return ERR_PTR(-EADDRNOTAVAIL); ++ else if (count == 0) ++ /* ++ * We can return ENOENT earlier than when register the ++ * kprobe. ++ */ ++ return ERR_PTR(-ENOENT); ++ } ++ + /* + * local trace_kprobes are not added to dyn_event, so they are never + * searched in find_trace_kprobe(). Therefore, there is no concern of +diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h +index 0f0e5005b97a0..82e1df8aefcb3 100644 +--- a/kernel/trace/trace_probe.h ++++ b/kernel/trace/trace_probe.h +@@ -405,6 +405,7 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call, + C(BAD_MAXACT, "Invalid maxactive number"), \ + C(MAXACT_TOO_BIG, "Maxactive is too big"), \ + C(BAD_PROBE_ADDR, "Invalid probed address or symbol"), \ ++ C(NON_UNIQ_SYMBOL, "The symbol is not unique"), \ + C(BAD_RETPROBE, "Retprobe address must be an function entry"), \ + C(BAD_ADDR_SUFFIX, "Invalid probed address suffix"), \ + C(NO_GROUP_NAME, "Group name is not specified"), \ +-- +2.42.0 +