]> Gentwo Git Trees - linux/.git/commitdiff
tracing: uprobes: Cleanup __trace_uprobe_create() with __free()
authorMasami Hiramatsu (Google) <mhiramat@kernel.org>
Thu, 25 Sep 2025 00:56:47 +0000 (09:56 +0900)
committerMasami Hiramatsu (Google) <mhiramat@kernel.org>
Fri, 31 Oct 2025 16:10:29 +0000 (01:10 +0900)
Use __free() to cleanup ugly gotos in __trace_uprobe_create().

Link: https://lore.kernel.org/all/175509540482.193596.6541098946023873304.stgit@devnote2/
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
kernel/trace/trace_uprobe.c

index b3d39b5b0690bd5e5e66a5ea10b070aab70e1156..d1d9abbe624833c241dbc623d1662ae1b808d960 100644 (file)
@@ -533,22 +533,25 @@ static int register_trace_uprobe(struct trace_uprobe *tu)
        return ret;
 }
 
+DEFINE_FREE(free_trace_uprobe, struct trace_uprobe *, if (_T) free_trace_uprobe(_T))
+
 /*
  * Argument syntax:
  *  - Add uprobe: p|r[:[GRP/][EVENT]] PATH:OFFSET[%return][(REF)] [FETCHARGS]
  */
 static int __trace_uprobe_create(int argc, const char **argv)
 {
+       struct trace_uprobe *tu __free(free_trace_uprobe) = NULL;
        const char *trlog __free(trace_probe_log_clear) = NULL;
        const char *event = NULL, *group = UPROBE_EVENT_SYSTEM;
-       char *arg, *filename, *rctr, *rctr_end, *tmp;
+       struct path path __free(path_put) = {};
        unsigned long offset, ref_ctr_offset;
+       char *filename __free(kfree) = NULL;
+       char *arg, *rctr, *rctr_end, *tmp;
        char *gbuf __free(kfree) = NULL;
        char *buf __free(kfree) = NULL;
        enum probe_print_type ptype;
-       struct trace_uprobe *tu;
        bool is_return = false;
-       struct path path;
        int i, ret;
 
        ref_ctr_offset = 0;
@@ -586,10 +589,8 @@ static int __trace_uprobe_create(int argc, const char **argv)
 
        /* Find the last occurrence, in case the path contains ':' too. */
        arg = strrchr(filename, ':');
-       if (!arg || !isdigit(arg[1])) {
-               kfree(filename);
+       if (!arg || !isdigit(arg[1]))
                return -ECANCELED;
-       }
 
        trace_probe_log_set_index(1);   /* filename is the 2nd argument */
 
@@ -597,13 +598,11 @@ static int __trace_uprobe_create(int argc, const char **argv)
        ret = kern_path(filename, LOOKUP_FOLLOW, &path);
        if (ret) {
                trace_probe_log_err(0, FILE_NOT_FOUND);
-               kfree(filename);
                return ret;
        }
        if (!d_is_reg(path.dentry)) {
                trace_probe_log_err(0, NO_REGULAR_FILE);
-               ret = -EINVAL;
-               goto fail_address_parse;
+               return -EINVAL;
        }
 
        /* Parse reference counter offset if specified. */
@@ -611,16 +610,14 @@ static int __trace_uprobe_create(int argc, const char **argv)
        if (rctr) {
                rctr_end = strchr(rctr, ')');
                if (!rctr_end) {
-                       ret = -EINVAL;
                        rctr_end = rctr + strlen(rctr);
                        trace_probe_log_err(rctr_end - filename,
                                            REFCNT_OPEN_BRACE);
-                       goto fail_address_parse;
+                       return -EINVAL;
                } else if (rctr_end[1] != '\0') {
-                       ret = -EINVAL;
                        trace_probe_log_err(rctr_end + 1 - filename,
                                            BAD_REFCNT_SUFFIX);
-                       goto fail_address_parse;
+                       return -EINVAL;
                }
 
                *rctr++ = '\0';
@@ -628,7 +625,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
                ret = kstrtoul(rctr, 0, &ref_ctr_offset);
                if (ret) {
                        trace_probe_log_err(rctr - filename, BAD_REFCNT);
-                       goto fail_address_parse;
+                       return ret;
                }
        }
 
@@ -640,8 +637,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
                        is_return = true;
                } else {
                        trace_probe_log_err(tmp - filename, BAD_ADDR_SUFFIX);
-                       ret = -EINVAL;
-                       goto fail_address_parse;
+                       return -EINVAL;
                }
        }
 
@@ -649,7 +645,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
        ret = kstrtoul(arg, 0, &offset);
        if (ret) {
                trace_probe_log_err(arg - filename, BAD_UPROBE_OFFS);
-               goto fail_address_parse;
+               return ret;
        }
 
        /* setup a probe */
@@ -657,12 +653,12 @@ static int __trace_uprobe_create(int argc, const char **argv)
        if (event) {
                gbuf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL);
                if (!gbuf)
-                       goto fail_mem;
+                       return -ENOMEM;
 
                ret = traceprobe_parse_event_name(&event, &group, gbuf,
                                                  event - argv[0]);
                if (ret)
-                       goto fail_address_parse;
+                       return ret;
        }
 
        if (!event) {
@@ -671,7 +667,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
 
                tail = kstrdup(kbasename(filename), GFP_KERNEL);
                if (!tail)
-                       goto fail_mem;
+                       return -ENOMEM;
 
                ptr = strpbrk(tail, ".-_");
                if (ptr)
@@ -679,7 +675,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
 
                buf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL);
                if (!buf)
-                       goto fail_mem;
+                       return -ENOMEM;
                snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_0x%lx", 'p', tail, offset);
                event = buf;
                kfree(tail);
@@ -693,49 +689,37 @@ static int __trace_uprobe_create(int argc, const char **argv)
                ret = PTR_ERR(tu);
                /* This must return -ENOMEM otherwise there is a bug */
                WARN_ON_ONCE(ret != -ENOMEM);
-               goto fail_address_parse;
+               return ret;
        }
        tu->offset = offset;
        tu->ref_ctr_offset = ref_ctr_offset;
        tu->path = path;
-       tu->filename = filename;
+       /* Clear @path so that it will not freed by path_put() */
+       memset(&path, 0, sizeof(path));
+       tu->filename = no_free_ptr(filename);
 
        /* parse arguments */
        for (i = 0; i < argc; i++) {
                struct traceprobe_parse_context *ctx __free(traceprobe_parse_context)
                        = kzalloc(sizeof(*ctx), GFP_KERNEL);
 
-               if (!ctx) {
-                       ret = -ENOMEM;
-                       goto error;
-               }
+               if (!ctx)
+                       return -ENOMEM;
                ctx->flags = (is_return ? TPARG_FL_RETURN : 0) | TPARG_FL_USER;
                trace_probe_log_set_index(i + 2);
                ret = traceprobe_parse_probe_arg(&tu->tp, i, argv[i], ctx);
                if (ret)
-                       goto error;
+                       return ret;
        }
 
        ptype = is_ret_probe(tu) ? PROBE_PRINT_RETURN : PROBE_PRINT_NORMAL;
        ret = traceprobe_set_print_fmt(&tu->tp, ptype);
        if (ret < 0)
-               goto error;
+               return ret;
 
        ret = register_trace_uprobe(tu);
        if (!ret)
-               goto out;
-
-error:
-       free_trace_uprobe(tu);
-out:
-       return ret;
-
-fail_mem:
-       ret = -ENOMEM;
-
-fail_address_parse:
-       path_put(&path);
-       kfree(filename);
+               tu = NULL;
 
        return ret;
 }