From 3e2b10a6f4d6c2b271b9eee292032a1aad3a205f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 3 Jan 2024 11:36:35 +0100 Subject: [PATCH] 5.4-stable patches added patches: tracing-kprobes-return-eaddrnotavail-when-func-matches-several-symbols.patch --- queue-5.4/series | 1 + ...il-when-func-matches-several-symbols.patch | 149 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 queue-5.4/tracing-kprobes-return-eaddrnotavail-when-func-matches-several-symbols.patch diff --git a/queue-5.4/series b/queue-5.4/series index 9bfe5014fe9..836e7d61afd 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -44,3 +44,4 @@ smb-client-fix-oob-in-smbcalcsize.patch bus-ti-sysc-use-fsleep-instead-of-usleep_range-in-sy.patch bus-ti-sysc-flush-posted-write-only-after-srst_udela.patch ring-buffer-fix-wake-ups-when-buffer_percent-is-set-to-100.patch +tracing-kprobes-return-eaddrnotavail-when-func-matches-several-symbols.patch diff --git a/queue-5.4/tracing-kprobes-return-eaddrnotavail-when-func-matches-several-symbols.patch b/queue-5.4/tracing-kprobes-return-eaddrnotavail-when-func-matches-several-symbols.patch new file mode 100644 index 00000000000..eae4c1614c4 --- /dev/null +++ b/queue-5.4/tracing-kprobes-return-eaddrnotavail-when-func-matches-several-symbols.patch @@ -0,0 +1,149 @@ +From b022f0c7e404887a7c5229788fc99eff9f9a80d5 Mon Sep 17 00:00:00 2001 +From: Francis Laniel +Date: Fri, 20 Oct 2023 13:42:49 +0300 +Subject: tracing/kprobes: Return EADDRNOTAVAIL when func matches several symbols + +From: Francis Laniel + +commit b022f0c7e404887a7c5229788fc99eff9f9a80d5 upstream. + +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: Greg Kroah-Hartman +--- + kernel/trace/trace_kprobe.c | 74 ++++++++++++++++++++++++++++++++++++++++++++ + kernel/trace/trace_probe.h | 1 + 2 files changed, 75 insertions(+) + +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -714,6 +714,36 @@ static inline void sanitize_event_name(c + *name = '_'; + } + ++struct count_symbols_struct { ++ const char *func_name; ++ unsigned int count; ++}; ++ ++static int count_symbols(void *data, const char *name, struct module *unused0, ++ unsigned long unused1) ++{ ++ struct count_symbols_struct *args = data; ++ ++ if (strcmp(args->func_name, name)) ++ return 0; ++ ++ args->count++; ++ ++ return 0; ++} ++ ++static unsigned int number_of_same_symbols(char *func_name) ++{ ++ struct count_symbols_struct args = { ++ .func_name = func_name, ++ .count = 0, ++ }; ++ ++ kallsyms_on_each_symbol(count_symbols, &args); ++ ++ return args.count; ++} ++ + static int trace_kprobe_create(int argc, const char *argv[]) + { + /* +@@ -825,6 +855,31 @@ static int trace_kprobe_create(int argc, + } + } + ++ 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, +@@ -1596,6 +1651,7 @@ static int unregister_kprobe_event(struc + } + + #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, +@@ -1605,6 +1661,24 @@ create_local_trace_kprobe(char *func, vo + 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 +--- a/kernel/trace/trace_probe.h ++++ b/kernel/trace/trace_probe.h +@@ -403,6 +403,7 @@ extern int traceprobe_define_arg_fields( + 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(NO_GROUP_NAME, "Group name is not specified"), \ + C(GROUP_TOO_LONG, "Group name is too long"), \ -- 2.47.3