Skip to content

Commit 6bc24db

Browse files
mikelrgregkh
authored andcommitted
tracing/probes: Fix MAX_TRACE_ARGS limit handling
[ Upstream commit 73f3508 ] When creating a trace_probe we would set nr_args prior to truncating the arguments to MAX_TRACE_ARGS. However, we would only initialize arguments up to the limit. This caused invalid memory access when attempting to set up probes with more than 128 fetchargs. BUG: kernel NULL pointer dereference, address: 0000000000000020 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: Oops: 0000 [#1] PREEMPT SMP PTI CPU: 0 UID: 0 PID: 1769 Comm: cat Not tainted 6.11.0-rc7+ #8 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-1.fc39 04/01/2014 RIP: 0010:__set_print_fmt+0x134/0x330 Resolve the issue by applying the MAX_TRACE_ARGS limit earlier. Return an error when there are too many arguments instead of silently truncating. Link: https://lore.kernel.org/all/20240930202656.292869-1-mikel@mikelr.com/ Fixes: 035ba76 ("tracing/probes: cleanup: Set trace_probe::nr_args at trace_probe_init") Signed-off-by: Mikel Rychliski <mikel@mikelr.com> Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent f475d8a commit 6bc24db

File tree

4 files changed

+19
-4
lines changed

4 files changed

+19
-4
lines changed

kernel/trace/trace_eprobe.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,11 @@ static int __trace_eprobe_create(int argc, const char *argv[])
915915
}
916916
}
917917

918+
if (argc - 2 > MAX_TRACE_ARGS) {
919+
ret = -E2BIG;
920+
goto error;
921+
}
922+
918923
mutex_lock(&event_mutex);
919924
event_call = find_and_get_event(sys_name, sys_event);
920925
ep = alloc_event_probe(group, event, event_call, argc - 2);
@@ -940,7 +945,7 @@ static int __trace_eprobe_create(int argc, const char *argv[])
940945

941946
argc -= 2; argv += 2;
942947
/* parse arguments */
943-
for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
948+
for (i = 0; i < argc; i++) {
944949
trace_probe_log_set_index(i + 2);
945950
ret = trace_eprobe_tp_update_arg(ep, argv, i);
946951
if (ret)

kernel/trace/trace_fprobe.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,10 @@ static int __trace_fprobe_create(int argc, const char *argv[])
11031103
argc = new_argc;
11041104
argv = new_argv;
11051105
}
1106+
if (argc > MAX_TRACE_ARGS) {
1107+
ret = -E2BIG;
1108+
goto out;
1109+
}
11061110

11071111
/* setup a probe */
11081112
tf = alloc_trace_fprobe(group, event, symbol, tpoint, maxactive,
@@ -1119,7 +1123,7 @@ static int __trace_fprobe_create(int argc, const char *argv[])
11191123
(unsigned long)tf->tpoint->probestub);
11201124

11211125
/* parse arguments */
1122-
for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
1126+
for (i = 0; i < argc; i++) {
11231127
trace_probe_log_set_index(i + 2);
11241128
ctx.offset = 0;
11251129
ret = traceprobe_parse_probe_arg(&tf->tp, i, argv[i], &ctx);

kernel/trace/trace_kprobe.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,10 @@ static int __trace_kprobe_create(int argc, const char *argv[])
932932
argc = new_argc;
933933
argv = new_argv;
934934
}
935+
if (argc > MAX_TRACE_ARGS) {
936+
ret = -E2BIG;
937+
goto out;
938+
}
935939

936940
/* setup a probe */
937941
tk = alloc_trace_kprobe(group, event, addr, symbol, offset, maxactive,
@@ -944,7 +948,7 @@ static int __trace_kprobe_create(int argc, const char *argv[])
944948
}
945949

946950
/* parse arguments */
947-
for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
951+
for (i = 0; i < argc; i++) {
948952
trace_probe_log_set_index(i + 2);
949953
ctx.offset = 0;
950954
ret = traceprobe_parse_probe_arg(&tk->tp, i, argv[i], &ctx);

kernel/trace/trace_uprobe.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,8 @@ static int __trace_uprobe_create(int argc, const char **argv)
556556

557557
if (argc < 2)
558558
return -ECANCELED;
559+
if (argc - 2 > MAX_TRACE_ARGS)
560+
return -E2BIG;
559561

560562
if (argv[0][1] == ':')
561563
event = &argv[0][2];
@@ -681,7 +683,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
681683
tu->filename = filename;
682684

683685
/* parse arguments */
684-
for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
686+
for (i = 0; i < argc; i++) {
685687
struct traceprobe_parse_context ctx = {
686688
.flags = (is_return ? TPARG_FL_RETURN : 0) | TPARG_FL_USER,
687689
};

0 commit comments

Comments
 (0)