mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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: Masami Hiramatsu (Google) <mhiramat@kernel.org> Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
This commit is contained in:
		
							parent
							
								
									d643eaa708
								
							
						
					
					
						commit
						33b4e38baa
					
				
					 1 changed files with 28 additions and 17 deletions
				
			
		| 
						 | 
					@ -861,20 +861,20 @@ static int trace_kprobe_create_internal(int argc, const char *argv[],
 | 
				
			||||||
	 *  FETCHARG:TYPE : use TYPE instead of unsigned long.
 | 
						 *  FETCHARG:TYPE : use TYPE instead of unsigned long.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	struct trace_kprobe *tk __free(free_trace_kprobe) = NULL;
 | 
						struct trace_kprobe *tk __free(free_trace_kprobe) = 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;
 | 
						const char *event = NULL, *group = KPROBE_EVENT_SYSTEM;
 | 
				
			||||||
	enum probe_print_type ptype;
 | 
						const char **new_argv __free(kfree) = NULL;
 | 
				
			||||||
	int maxactive = 0;
 | 
						int i, len, new_argc = 0, ret = 0;
 | 
				
			||||||
	long offset = 0;
 | 
						char *symbol __free(kfree) = NULL;
 | 
				
			||||||
	void *addr = NULL;
 | 
						char *ebuf __free(kfree) = NULL;
 | 
				
			||||||
	char buf[MAX_EVENT_NAME_LEN];
 | 
						char *gbuf __free(kfree) = NULL;
 | 
				
			||||||
	char gbuf[MAX_EVENT_NAME_LEN];
 | 
						char *abuf __free(kfree) = NULL;
 | 
				
			||||||
	char abuf[MAX_BTF_ARGS_LEN];
 | 
					 | 
				
			||||||
	char *dbuf __free(kfree) = NULL;
 | 
						char *dbuf __free(kfree) = NULL;
 | 
				
			||||||
 | 
						enum probe_print_type ptype;
 | 
				
			||||||
 | 
						bool is_return = false;
 | 
				
			||||||
 | 
						int maxactive = 0;
 | 
				
			||||||
 | 
						void *addr = NULL;
 | 
				
			||||||
 | 
						char *tmp = NULL;
 | 
				
			||||||
 | 
						long offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (argv[0][0]) {
 | 
						switch (argv[0][0]) {
 | 
				
			||||||
	case 'r':
 | 
						case 'r':
 | 
				
			||||||
| 
						 | 
					@ -893,6 +893,8 @@ static int trace_kprobe_create_internal(int argc, const char *argv[],
 | 
				
			||||||
		event++;
 | 
							event++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (isdigit(argv[0][1])) {
 | 
						if (isdigit(argv[0][1])) {
 | 
				
			||||||
 | 
							char *buf __free(kfree) = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!is_return) {
 | 
							if (!is_return) {
 | 
				
			||||||
			trace_probe_log_err(1, BAD_MAXACT_TYPE);
 | 
								trace_probe_log_err(1, BAD_MAXACT_TYPE);
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
| 
						 | 
					@ -905,7 +907,7 @@ static int trace_kprobe_create_internal(int argc, const char *argv[],
 | 
				
			||||||
			trace_probe_log_err(1, BAD_MAXACT);
 | 
								trace_probe_log_err(1, BAD_MAXACT);
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		memcpy(buf, &argv[0][1], len);
 | 
							buf = kmemdup(&argv[0][1], len + 1, GFP_KERNEL);
 | 
				
			||||||
		buf[len] = '\0';
 | 
							buf[len] = '\0';
 | 
				
			||||||
		ret = kstrtouint(buf, 0, &maxactive);
 | 
							ret = kstrtouint(buf, 0, &maxactive);
 | 
				
			||||||
		if (ret || !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);
 | 
						trace_probe_log_set_index(0);
 | 
				
			||||||
	if (event) {
 | 
						if (event) {
 | 
				
			||||||
 | 
							gbuf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!gbuf)
 | 
				
			||||||
 | 
								return -ENOMEM;
 | 
				
			||||||
		ret = traceprobe_parse_event_name(&event, &group, gbuf,
 | 
							ret = traceprobe_parse_event_name(&event, &group, gbuf,
 | 
				
			||||||
						  event - argv[0]);
 | 
											  event - argv[0]);
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
| 
						 | 
					@ -981,16 +986,22 @@ static int trace_kprobe_create_internal(int argc, const char *argv[],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!event) {
 | 
						if (!event) {
 | 
				
			||||||
		/* Make a new event name */
 | 
							/* Make a new event name */
 | 
				
			||||||
 | 
							ebuf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!ebuf)
 | 
				
			||||||
 | 
								return -ENOMEM;
 | 
				
			||||||
		if (symbol)
 | 
							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);
 | 
									 is_return ? 'r' : 'p', symbol, offset);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			snprintf(buf, MAX_EVENT_NAME_LEN, "%c_0x%p",
 | 
								snprintf(ebuf, MAX_EVENT_NAME_LEN, "%c_0x%p",
 | 
				
			||||||
				 is_return ? 'r' : 'p', addr);
 | 
									 is_return ? 'r' : 'p', addr);
 | 
				
			||||||
		sanitize_event_name(buf);
 | 
							sanitize_event_name(ebuf);
 | 
				
			||||||
		event = buf;
 | 
							event = ebuf;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						abuf = kmalloc(MAX_BTF_ARGS_LEN, GFP_KERNEL);
 | 
				
			||||||
 | 
						if (!abuf)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
	argc -= 2; argv += 2;
 | 
						argc -= 2; argv += 2;
 | 
				
			||||||
	ctx->funcname = symbol;
 | 
						ctx->funcname = symbol;
 | 
				
			||||||
	new_argv = traceprobe_expand_meta_args(argc, argv, &new_argc,
 | 
						new_argv = traceprobe_expand_meta_args(argc, argv, &new_argc,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue