]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tracing: kprobe-event: Allocate string buffers from heap
authorMasami Hiramatsu (Google) <mhiramat@kernel.org>
Wed, 23 Jul 2025 01:31:16 +0000 (10:31 +0900)
committerMasami Hiramatsu (Google) <mhiramat@kernel.org>
Wed, 23 Jul 2025 15:21:44 +0000 (00:21 +0900)
Allocate temporary string buffers for parsing kprobe-events
from heap instead of stack.

Link: https://lore.kernel.org/all/175323427627.57270.5105357260879695051.stgit@devnote2/
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
kernel/trace/trace_kprobe.c

index d14b33e205f7f4aa198cac6553f96e96ce47b228..ccae62d4fb91776e389f83217bedbb4c35400abd 100644 (file)
@@ -861,20 +861,20 @@ static int trace_kprobe_create_internal(int argc, const char *argv[],
         *  FETCHARG:TYPE : use TYPE instead of unsigned long.
         */
        struct trace_kprobe *tk __free(free_trace_kprobe) = NULL;
+       const char *event = NULL, *group = KPROBE_EVENT_SYSTEM;
+       const char **new_argv __free(kfree) = NULL;
        int i, len, new_argc = 0, ret = 0;
-       bool is_return = false;
        char *symbol __free(kfree) = NULL;
-       char *tmp = NULL;
-       const char **new_argv __free(kfree) = NULL;
-       const char *event = NULL, *group = KPROBE_EVENT_SYSTEM;
+       char *ebuf __free(kfree) = NULL;
+       char *gbuf __free(kfree) = NULL;
+       char *abuf __free(kfree) = NULL;
+       char *dbuf __free(kfree) = NULL;
        enum probe_print_type ptype;
+       bool is_return = false;
        int maxactive = 0;
-       long offset = 0;
        void *addr = NULL;
-       char buf[MAX_EVENT_NAME_LEN];
-       char gbuf[MAX_EVENT_NAME_LEN];
-       char abuf[MAX_BTF_ARGS_LEN];
-       char *dbuf __free(kfree) = NULL;
+       char *tmp = NULL;
+       long offset = 0;
 
        switch (argv[0][0]) {
        case 'r':
@@ -893,6 +893,8 @@ static int trace_kprobe_create_internal(int argc, const char *argv[],
                event++;
 
        if (isdigit(argv[0][1])) {
+               char *buf __free(kfree) = NULL;
+
                if (!is_return) {
                        trace_probe_log_err(1, BAD_MAXACT_TYPE);
                        return -EINVAL;
@@ -905,7 +907,7 @@ static int trace_kprobe_create_internal(int argc, const char *argv[],
                        trace_probe_log_err(1, BAD_MAXACT);
                        return -EINVAL;
                }
-               memcpy(buf, &argv[0][1], len);
+               buf = kmemdup(&argv[0][1], len + 1, GFP_KERNEL);
                buf[len] = '\0';
                ret = kstrtouint(buf, 0, &maxactive);
                if (ret || !maxactive) {
@@ -973,6 +975,9 @@ static int trace_kprobe_create_internal(int argc, const char *argv[],
 
        trace_probe_log_set_index(0);
        if (event) {
+               gbuf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL);
+               if (!gbuf)
+                       return -ENOMEM;
                ret = traceprobe_parse_event_name(&event, &group, gbuf,
                                                  event - argv[0]);
                if (ret)
@@ -981,16 +986,22 @@ static int trace_kprobe_create_internal(int argc, const char *argv[],
 
        if (!event) {
                /* Make a new event name */
+               ebuf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL);
+               if (!ebuf)
+                       return -ENOMEM;
                if (symbol)
-                       snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_%ld",
+                       snprintf(ebuf, MAX_EVENT_NAME_LEN, "%c_%s_%ld",
                                 is_return ? 'r' : 'p', symbol, offset);
                else
-                       snprintf(buf, MAX_EVENT_NAME_LEN, "%c_0x%p",
+                       snprintf(ebuf, MAX_EVENT_NAME_LEN, "%c_0x%p",
                                 is_return ? 'r' : 'p', addr);
-               sanitize_event_name(buf);
-               event = buf;
+               sanitize_event_name(ebuf);
+               event = ebuf;
        }
 
+       abuf = kmalloc(MAX_BTF_ARGS_LEN, GFP_KERNEL);
+       if (!abuf)
+               return -ENOMEM;
        argc -= 2; argv += 2;
        ctx->funcname = symbol;
        new_argv = traceprobe_expand_meta_args(argc, argv, &new_argc,