Skip to content

Commit d4505aa

Browse files
committed
tracing/probes: Reject symbol/symstr type for uprobe
Since uprobe's argument must contain the user-space data, that should not be converted to kernel symbols. Reject if user specifies these types on uprobe events. e.g. /sys/kernel/debug/tracing # echo 'p /bin/sh:10 %ax:symbol' >> uprobe_events sh: write error: Invalid argument /sys/kernel/debug/tracing # echo 'p /bin/sh:10 %ax:symstr' >> uprobe_events sh: write error: Invalid argument /sys/kernel/debug/tracing # cat error_log [ 1783.134883] trace_uprobe: error: Unknown type is specified Command: p /bin/sh:10 %ax:symbol ^ [ 1792.201120] trace_uprobe: error: Unknown type is specified Command: p /bin/sh:10 %ax:symstr ^ Link: https://lore.kernel.org/all/166679931679.1528100.15540755370726009882.stgit@devnote3/ Signed-off-by: Masami Hiramatsu (Google) <[email protected]>
1 parent b26a124 commit d4505aa

File tree

4 files changed

+22
-10
lines changed

4 files changed

+22
-10
lines changed

kernel/trace/trace_probe.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,15 @@ static const struct fetch_type probe_fetch_types[] = {
100100
ASSIGN_FETCH_TYPE_END
101101
};
102102

103-
static const struct fetch_type *find_fetch_type(const char *type)
103+
static const struct fetch_type *find_fetch_type(const char *type, unsigned long flags)
104104
{
105105
int i;
106106

107+
/* Reject the symbol/symstr for uprobes */
108+
if (type && (flags & TPARG_FL_USER) &&
109+
(!strcmp(type, "symbol") || !strcmp(type, "symstr")))
110+
return NULL;
111+
107112
if (!type)
108113
type = DEFAULT_FETCH_TYPE_STR;
109114

@@ -121,13 +126,13 @@ static const struct fetch_type *find_fetch_type(const char *type)
121126

122127
switch (bs) {
123128
case 8:
124-
return find_fetch_type("u8");
129+
return find_fetch_type("u8", flags);
125130
case 16:
126-
return find_fetch_type("u16");
131+
return find_fetch_type("u16", flags);
127132
case 32:
128-
return find_fetch_type("u32");
133+
return find_fetch_type("u32", flags);
129134
case 64:
130-
return find_fetch_type("u64");
135+
return find_fetch_type("u64", flags);
131136
default:
132137
goto fail;
133138
}
@@ -480,7 +485,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
480485
DEREF_OPEN_BRACE);
481486
return -EINVAL;
482487
} else {
483-
const struct fetch_type *t2 = find_fetch_type(NULL);
488+
const struct fetch_type *t2 = find_fetch_type(NULL, flags);
484489

485490
*tmp = '\0';
486491
ret = parse_probe_arg(arg, t2, &code, end, flags, offs);
@@ -632,9 +637,9 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
632637
/* The type of $comm must be "string", and not an array. */
633638
if (parg->count || (t && strcmp(t, "string")))
634639
goto out;
635-
parg->type = find_fetch_type("string");
640+
parg->type = find_fetch_type("string", flags);
636641
} else
637-
parg->type = find_fetch_type(t);
642+
parg->type = find_fetch_type(t, flags);
638643
if (!parg->type) {
639644
trace_probe_log_err(offset + (t ? (t - arg) : 0), BAD_TYPE);
640645
goto out;

kernel/trace/trace_probe.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,8 @@ int trace_probe_create(const char *raw_command, int (*createfn)(int, const char
358358
#define TPARG_FL_KERNEL BIT(1)
359359
#define TPARG_FL_FENTRY BIT(2)
360360
#define TPARG_FL_TPOINT BIT(3)
361-
#define TPARG_FL_MASK GENMASK(3, 0)
361+
#define TPARG_FL_USER BIT(4)
362+
#define TPARG_FL_MASK GENMASK(4, 0)
362363

363364
extern int traceprobe_parse_probe_arg(struct trace_probe *tp, int i,
364365
const char *argv, unsigned int flags);

kernel/trace/trace_uprobe.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,8 @@ static int __trace_uprobe_create(int argc, const char **argv)
691691
for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
692692
trace_probe_log_set_index(i + 2);
693693
ret = traceprobe_parse_probe_arg(&tu->tp, i, argv[i],
694-
is_return ? TPARG_FL_RETURN : 0);
694+
(is_return ? TPARG_FL_RETURN : 0) |
695+
TPARG_FL_USER);
695696
if (ret)
696697
goto error;
697698
}

tools/testing/selftests/ftrace/test.d/kprobe/uprobe_syntax_errors.tc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,9 @@ check_error 'p /bin/sh:10^%hoge' # BAD_ADDR_SUFFIX
2323
check_error 'p /bin/sh:10(10)^%return' # BAD_REFCNT_SUFFIX
2424
fi
2525

26+
# symstr is not supported by uprobe
27+
if grep -q ".*symstr.*" README; then
28+
check_error 'p /bin/sh:10 $stack0:^symstr' # BAD_TYPE
29+
fi
30+
2631
exit 0

0 commit comments

Comments
 (0)