aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasami Hiramatsu (Google) <mhiramat@kernel.org>2023-06-29 09:58:39 +0900
committerMasami Hiramatsu (Google) <mhiramat@kernel.org>2023-06-29 10:00:02 +0900
commitc8be1ba8b966d8fa1f95ec45773b0e3cfc8981f7 (patch)
tree715989a56f4a0bc22afca268d1a1f59a8c722437
parentfc739a50dc8625466a38da0d40fdbf725e4ea60b (diff)
downloadlinux-topic/fix-probe-template.tar.gz
tracing/probes: Fix return value when "(fault)" is injectedtopic/fix-probe-template
When the "(fault)" is injected, the return value of fetch_store_string*() must be the length of the "(fault)", but it returns error code. Fix it to return correct length, and cleanup the variable name to be more readable. Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Link: https://lore.kernel.org/all/8819b154-2ba1-43c3-98a2-cbde20892023@moroto.mountain/ Fixes: 2e9906f84fc7 ("tracing: Add "(fault)" name injection to kernel probes") Cc: stable@vger.kernel.org Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-rw-r--r--kernel/trace/trace_probe_kernel.h44
1 files changed, 23 insertions, 21 deletions
diff --git a/kernel/trace/trace_probe_kernel.h b/kernel/trace/trace_probe_kernel.h
index c4e1d4c03a85f..bc05e145351a7 100644
--- a/kernel/trace/trace_probe_kernel.h
+++ b/kernel/trace/trace_probe_kernel.h
@@ -48,14 +48,18 @@ fetch_store_strlen(unsigned long addr)
return (ret < 0) ? strlen(FAULT_STRING) + 1 : len;
}
-static nokprobe_inline void set_data_loc(int ret, void *dest, void *__dest, void *base, int len)
+static nokprobe_inline int set_data_loc(int ret,
+ void *dest_entry,
+ void *dest_data,
+ void *base, int len)
{
- if (ret >= 0) {
- *(u32 *)dest = make_data_loc(ret, __dest - base);
- } else {
- strscpy(__dest, FAULT_STRING, len);
- ret = strlen(__dest) + 1;
+ if (ret < 0) {
+ strscpy(dest_data, FAULT_STRING, len);
+ ret = strlen(dest_data) + 1;
}
+ *(u32 *)dest_entry = make_data_loc(ret, dest_data - base);
+
+ return ret;
}
/*
@@ -63,22 +67,21 @@ static nokprobe_inline void set_data_loc(int ret, void *dest, void *__dest, void
* with max length and relative data location.
*/
static nokprobe_inline int
-fetch_store_string_user(unsigned long addr, void *dest, void *base)
+fetch_store_string_user(unsigned long addr, void *dest_entry, void *base)
{
const void __user *uaddr = (__force const void __user *)addr;
- int maxlen = get_loc_len(*(u32 *)dest);
- void *__dest;
+ int maxlen = get_loc_len(*(u32 *)dest_entry);
+ void *dest_data;
long ret;
if (unlikely(!maxlen))
return -ENOMEM;
- __dest = get_loc_data(dest, base);
+ dest_data = get_loc_data(dest_entry, base);
- ret = strncpy_from_user_nofault(__dest, uaddr, maxlen);
- set_data_loc(ret, dest, __dest, base, maxlen);
+ ret = strncpy_from_user_nofault(dest_data, uaddr, maxlen);
- return ret;
+ return set_data_loc(ret, dest_entry, dest_data, base, maxlen);
}
/*
@@ -86,30 +89,29 @@ fetch_store_string_user(unsigned long addr, void *dest, void *base)
* length and relative data location.
*/
static nokprobe_inline int
-fetch_store_string(unsigned long addr, void *dest, void *base)
+fetch_store_string(unsigned long addr, void *dest_entry, void *base)
{
- int maxlen = get_loc_len(*(u32 *)dest);
- void *__dest;
+ int maxlen = get_loc_len(*(u32 *)dest_entry);
+ void *dest_data;
long ret;
#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
if ((unsigned long)addr < TASK_SIZE)
- return fetch_store_string_user(addr, dest, base);
+ return fetch_store_string_user(addr, dest_entry, base);
#endif
if (unlikely(!maxlen))
return -ENOMEM;
- __dest = get_loc_data(dest, base);
+ dest_data = get_loc_data(dest_entry, base);
/*
* Try to get string again, since the string can be changed while
* probing.
*/
- ret = strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen);
- set_data_loc(ret, dest, __dest, base, maxlen);
+ ret = strncpy_from_kernel_nofault(dest_data, (void *)addr, maxlen);
- return ret;
+ return set_data_loc(ret, dest_entry, dest_data, base, maxlen);
}
static nokprobe_inline int