]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Sat, 9 Dec 2023 11:50:52 +0000 (06:50 -0500)
committerSasha Levin <sashal@kernel.org>
Sun, 10 Dec 2023 02:03:04 +0000 (21:03 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.15/binder-fix-memory-leaks-of-spam-and-pending-work.patch [new file with mode: 0644]
queue-5.15/kallsyms-make-kallsyms_on_each_symbol-generally-avai.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/tracing-kprobes-return-eaddrnotavail-when-func-match.patch [new file with mode: 0644]

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 (file)
index 0000000..85e1583
--- /dev/null
@@ -0,0 +1,77 @@
+From 16f80599a2c254be8e6b4fe711280a7c9a0601ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Dec 2023 03:48:42 +0000
+Subject: binder: fix memory leaks of spam and pending work
+
+From: Carlos Llamas <cmllamas@google.com>
+
+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:
+    [<ffffffff81573b75>] kmalloc_trace+0x25/0x90 mm/slab_common.c:1114
+    [<ffffffff83d41873>] kmalloc include/linux/slab.h:599 [inline]
+    [<ffffffff83d41873>] kzalloc include/linux/slab.h:720 [inline]
+    [<ffffffff83d41873>] binder_transaction+0x573/0x4050 drivers/android/binder.c:3152
+    [<ffffffff83d45a05>] binder_thread_write+0x6b5/0x1860 drivers/android/binder.c:4010
+    [<ffffffff83d486dc>] binder_ioctl_write_read drivers/android/binder.c:5066 [inline]
+    [<ffffffff83d486dc>] binder_ioctl+0x1b2c/0x3cf0 drivers/android/binder.c:5352
+    [<ffffffff816b25f2>] vfs_ioctl fs/ioctl.c:51 [inline]
+    [<ffffffff816b25f2>] __do_sys_ioctl fs/ioctl.c:871 [inline]
+    [<ffffffff816b25f2>] __se_sys_ioctl fs/ioctl.c:857 [inline]
+    [<ffffffff816b25f2>] __x64_sys_ioctl+0xf2/0x140 fs/ioctl.c:857
+    [<ffffffff84b30008>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+    [<ffffffff84b30008>] do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
+    [<ffffffff84c0008b>] 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 <aliceryhl@google.com>
+Signed-off-by: Carlos Llamas <cmllamas@google.com>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Acked-by: Todd Kjos <tkjos@google.com>
+Link: https://lore.kernel.org/r/20230922175138.230331-1-cmllamas@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[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 <cmllamas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..ebc220f
--- /dev/null
@@ -0,0 +1,78 @@
+From 98aa2db59a072b52be5a8ec70c78e4dc632c031e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 May 2022 14:26:12 +0200
+Subject: kallsyms: Make kallsyms_on_each_symbol generally available
+
+From: Jiri Olsa <jolsa@kernel.org>
+
+[ 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 <hch@lst.de>
+Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
+Signed-off-by: Jiri Olsa <jolsa@kernel.org>
+Link: https://lore.kernel.org/r/20220510122616.2652285-2-jolsa@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
index 4a97dd0f52e03fa72686d73b0fe4b43cb94b1490..764b9ec14808e1f3e7ef2b75c6e7ffc9dbfc92fe 100644 (file)
@@ -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 (file)
index 0000000..5f954d2
--- /dev/null
@@ -0,0 +1,146 @@
+From 164d8ddbfff70475e9b3a87099a15ad04c97718d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Oct 2023 13:42:49 +0300
+Subject: tracing/kprobes: Return EADDRNOTAVAIL when func matches several
+ symbols
+
+From: Francis Laniel <flaniel@linux.microsoft.com>
+
+[ 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 <mhiramat@kernel.org>
+Signed-off-by: Francis Laniel <flaniel@linux.microsoft.com>
+Link: https://lore.kernel.org/lkml/20230819101105.b0c104ae4494a7d1f2eea742@kernel.org/
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+