Commit 43beb5e8 authored by Masami Hiramatsu (Google)'s avatar Masami Hiramatsu (Google)
Browse files

tracing: probe: Allocate traceprobe_parse_context from heap

Instead of allocating traceprobe_parse_context on stack, allocate it
dynamically from heap (slab).

This change is likely intended to prevent potential stack overflow
issues, which can be a concern in the kernel environment where stack
space is limited.

Link: https://lore.kernel.org/all/175323425650.57270.280750740753792504.stgit@devnote2/



Reported-by: default avatarkernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202506240416.nZIhDXoO-lkp@intel.com/


Signed-off-by: default avatarMasami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
parent 2f02a61d
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -797,18 +797,20 @@ find_and_get_event(const char *system, const char *event_name)

static int trace_eprobe_tp_update_arg(struct trace_eprobe *ep, const char *argv[], int i)
{
	struct traceprobe_parse_context ctx = {
		.event = ep->event,
		.flags = TPARG_FL_KERNEL | TPARG_FL_TEVENT,
	};
	struct traceprobe_parse_context *ctx __free(traceprobe_parse_context) = NULL;
	int ret;

	ret = traceprobe_parse_probe_arg(&ep->tp, i, argv[i], &ctx);
	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;
	ctx->event = ep->event;
	ctx->flags = TPARG_FL_KERNEL | TPARG_FL_TEVENT;

	ret = traceprobe_parse_probe_arg(&ep->tp, i, argv[i], ctx);
	/* Handle symbols "@" */
	if (!ret)
		ret = traceprobe_update_arg(&ep->tp.args[i]);

	traceprobe_finish_parse(&ctx);
	return ret;
}

+8 −5
Original line number Diff line number Diff line
@@ -1384,14 +1384,17 @@ static int trace_fprobe_create_internal(int argc, const char *argv[],

static int trace_fprobe_create_cb(int argc, const char *argv[])
{
	struct traceprobe_parse_context ctx = {
		.flags = TPARG_FL_KERNEL | TPARG_FL_FPROBE,
	};
	struct traceprobe_parse_context *ctx __free(traceprobe_parse_context) = NULL;
	int ret;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	ctx->flags = TPARG_FL_KERNEL | TPARG_FL_FPROBE,

	trace_probe_log_init("trace_fprobe", argc, argv);
	ret = trace_fprobe_create_internal(argc, argv, &ctx);
	traceprobe_finish_parse(&ctx);
	ret = trace_fprobe_create_internal(argc, argv, ctx);
	trace_probe_log_clear();
	return ret;
}
+7 −3
Original line number Diff line number Diff line
@@ -1065,14 +1065,18 @@ static int trace_kprobe_create_internal(int argc, const char *argv[],

static int trace_kprobe_create_cb(int argc, const char *argv[])
{
	struct traceprobe_parse_context ctx = { .flags = TPARG_FL_KERNEL };
	struct traceprobe_parse_context *ctx __free(traceprobe_parse_context) = NULL;
	int ret;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;
	ctx->flags = TPARG_FL_KERNEL;

	trace_probe_log_init("trace_kprobe", argc, argv);

	ret = trace_kprobe_create_internal(argc, argv, &ctx);
	ret = trace_kprobe_create_internal(argc, argv, ctx);

	traceprobe_finish_parse(&ctx);
	trace_probe_log_clear();
	return ret;
}
+9 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@

#include <linux/bitops.h>
#include <linux/btf.h>
#include <linux/cleanup.h>
#include <linux/kprobes.h>
#include <linux/limits.h>
#include <linux/perf_event.h>
@@ -439,6 +440,14 @@ extern void traceprobe_free_probe_arg(struct probe_arg *arg);
 * this MUST be called for clean up the context and return a resource.
 */
void traceprobe_finish_parse(struct traceprobe_parse_context *ctx);
static inline void traceprobe_free_parse_ctx(struct traceprobe_parse_context *ctx)
{
	traceprobe_finish_parse(ctx);
	kfree(ctx);
}

DEFINE_FREE(traceprobe_parse_context, struct traceprobe_parse_context *,
	if (_T) traceprobe_free_parse_ctx(_T))

extern int traceprobe_split_symbol_offset(char *symbol, long *offset);
int traceprobe_parse_event_name(const char **pevent, const char **pgroup,
+8 −5
Original line number Diff line number Diff line
@@ -695,13 +695,16 @@ static int __trace_uprobe_create(int argc, const char **argv)

	/* parse arguments */
	for (i = 0; i < argc; i++) {
		struct traceprobe_parse_context ctx = {
			.flags = (is_return ? TPARG_FL_RETURN : 0) | TPARG_FL_USER,
		};
		struct traceprobe_parse_context *ctx __free(traceprobe_parse_context)
			= kzalloc(sizeof(*ctx), GFP_KERNEL);

		if (!ctx) {
			ret = -ENOMEM;
			goto error;
		}
		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);
		traceprobe_finish_parse(&ctx);
		ret = traceprobe_parse_probe_arg(&tu->tp, i, argv[i], ctx);
		if (ret)
			goto error;
	}