Commit 33b4e38b authored by Masami Hiramatsu (Google)'s avatar Masami Hiramatsu (Google)
Browse files

tracing: kprobe-event: Allocate string buffers from heap

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: default avatarMasami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
parent d643eaa7
Loading
Loading
Loading
Loading
+25 −14
Original line number Diff line number Diff line
@@ -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,