tracing/probes: Fix to set arg size and fmt after setting type from BTF
authorMasami Hiramatsu (Google) <mhiramat@kernel.org>
Tue, 23 Jan 2024 15:03:02 +0000 (00:03 +0900)
committerMasami Hiramatsu (Google) <mhiramat@kernel.org>
Thu, 8 Feb 2024 14:26:25 +0000 (23:26 +0900)
Since the BTF type setting updates probe_arg::type, the type size
calculation and setting print-fmt should be done after that.
Without this fix, the argument size and print-fmt can be wrong.

Link: https://lore.kernel.org/all/170602218196.215583.6417859469540955777.stgit@devnote2/
Fixes: b576e09701c7 ("tracing/probes: Support function parameters if BTF is available")
Cc: stable@vger.kernel.org
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
kernel/trace/trace_probe.c

index c6da5923e5b9f0fc94ca6f8e7d59b5b8b35102ee..34289f9c67076b2ab81ffc67bd5a518926e59ca6 100644 (file)
@@ -1172,18 +1172,6 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
                trace_probe_log_err(ctx->offset + (t ? (t - arg) : 0), BAD_TYPE);
                goto out;
        }
-       parg->offset = *size;
-       *size += parg->type->size * (parg->count ?: 1);
-
-       ret = -ENOMEM;
-       if (parg->count) {
-               len = strlen(parg->type->fmttype) + 6;
-               parg->fmt = kmalloc(len, GFP_KERNEL);
-               if (!parg->fmt)
-                       goto out;
-               snprintf(parg->fmt, len, "%s[%d]", parg->type->fmttype,
-                        parg->count);
-       }
 
        code = tmp = kcalloc(FETCH_INSN_MAX, sizeof(*code), GFP_KERNEL);
        if (!code)
@@ -1207,6 +1195,19 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
                                goto fail;
                }
        }
+       parg->offset = *size;
+       *size += parg->type->size * (parg->count ?: 1);
+
+       if (parg->count) {
+               len = strlen(parg->type->fmttype) + 6;
+               parg->fmt = kmalloc(len, GFP_KERNEL);
+               if (!parg->fmt) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               snprintf(parg->fmt, len, "%s[%d]", parg->type->fmttype,
+                        parg->count);
+       }
 
        ret = -EINVAL;
        /* Store operation */