Skip to content

Commit 2e9906f

Browse files
committed
tracing: Add "(fault)" name injection to kernel probes
Have the specific functions for kernel probes that read strings to inject the "(fault)" name directly. trace_probes.c does this too (for uprobes) but as the code to read strings are going to be used by synthetic events (and perhaps other utilities), it simplifies the code by making sure those other uses do not need to implement the "(fault)" name injection as well. Link: https://lkml.kernel.org/r/[email protected] Cc: [email protected] Cc: Andrew Morton <[email protected]> Cc: Tom Zanussi <[email protected]> Acked-by: Masami Hiramatsu (Google) <[email protected]> Reviewed-by: Tom Zanussi <[email protected]> Fixes: bd82631 ("tracing: Add support for dynamic strings to synthetic events") Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent f1d3cbf commit 2e9906f

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

kernel/trace/trace_probe_kernel.h

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#ifndef __TRACE_PROBE_KERNEL_H_
33
#define __TRACE_PROBE_KERNEL_H_
44

5+
#define FAULT_STRING "(fault)"
6+
57
/*
68
* This depends on trace_probe.h, but can not include it due to
79
* the way trace_probe_tmpl.h is used by trace_kprobe.c and trace_eprobe.c.
@@ -13,8 +15,16 @@ static nokprobe_inline int
1315
kern_fetch_store_strlen_user(unsigned long addr)
1416
{
1517
const void __user *uaddr = (__force const void __user *)addr;
18+
int ret;
1619

17-
return strnlen_user_nofault(uaddr, MAX_STRING_SIZE);
20+
ret = strnlen_user_nofault(uaddr, MAX_STRING_SIZE);
21+
/*
22+
* strnlen_user_nofault returns zero on fault, insert the
23+
* FAULT_STRING when that occurs.
24+
*/
25+
if (ret <= 0)
26+
return strlen(FAULT_STRING) + 1;
27+
return ret;
1828
}
1929

2030
/* Return the length of string -- including null terminal byte */
@@ -34,7 +44,18 @@ kern_fetch_store_strlen(unsigned long addr)
3444
len++;
3545
} while (c && ret == 0 && len < MAX_STRING_SIZE);
3646

37-
return (ret < 0) ? ret : len;
47+
/* For faults, return enough to hold the FAULT_STRING */
48+
return (ret < 0) ? strlen(FAULT_STRING) + 1 : len;
49+
}
50+
51+
static nokprobe_inline void set_data_loc(int ret, void *dest, void *__dest, void *base, int len)
52+
{
53+
if (ret >= 0) {
54+
*(u32 *)dest = make_data_loc(ret, __dest - base);
55+
} else {
56+
strscpy(__dest, FAULT_STRING, len);
57+
ret = strlen(__dest) + 1;
58+
}
3859
}
3960

4061
/*
@@ -55,8 +76,7 @@ kern_fetch_store_string_user(unsigned long addr, void *dest, void *base)
5576
__dest = get_loc_data(dest, base);
5677

5778
ret = strncpy_from_user_nofault(__dest, uaddr, maxlen);
58-
if (ret >= 0)
59-
*(u32 *)dest = make_data_loc(ret, __dest - base);
79+
set_data_loc(ret, dest, __dest, base, maxlen);
6080

6181
return ret;
6282
}
@@ -87,8 +107,7 @@ kern_fetch_store_string(unsigned long addr, void *dest, void *base)
87107
* probing.
88108
*/
89109
ret = strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen);
90-
if (ret >= 0)
91-
*(u32 *)dest = make_data_loc(ret, __dest - base);
110+
set_data_loc(ret, dest, __dest, base, maxlen);
92111

93112
return ret;
94113
}

0 commit comments

Comments
 (0)