Commit 023cc836 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'probes-fixes-v6.6-rc6.2' of...

Merge tag 'probes-fixes-v6.6-rc6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull probes fixes from Masami Hiramatsu:

 - kprobe-events: Fix kprobe events to reject if the attached symbol is
   not unique name because it may not the function which the user want
   to attach to. (User can attach a probe to such symbol using the
   nearest unique symbol + offset.)

 - selftest: Add a testcase to ensure the kprobe event rejects non
   unique symbol correctly.

* tag 'probes-fixes-v6.6-rc6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  selftests/ftrace: Add new test case which checks non unique symbol
  tracing/kprobes: Return EADDRNOTAVAIL when func matches several symbols
parents 4d7b04c0 03b80ff8
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
@@ -705,6 +705,25 @@ static struct notifier_block trace_kprobe_module_nb = {
	.priority = 1	/* Invoked after kprobe module callback */
};

static int count_symbols(void *data, unsigned long unused)
{
	unsigned int *count = data;

	(*count)++;

	return 0;
}

static unsigned int number_of_same_symbols(char *func_name)
{
	unsigned int count;

	count = 0;
	kallsyms_on_each_match_symbol(count_symbols, func_name, &count);

	return count;
}

static int __trace_kprobe_create(int argc, const char *argv[])
{
	/*
@@ -836,6 +855,31 @@ static int __trace_kprobe_create(int argc, const char *argv[])
		}
	}

	if (symbol && !strchr(symbol, ':')) {
		unsigned int count;

		count = number_of_same_symbols(symbol);
		if (count > 1) {
			/*
			 * Users should use ADDR to remove the ambiguity of
			 * using KSYM only.
			 */
			trace_probe_log_err(0, NON_UNIQ_SYMBOL);
			ret = -EADDRNOTAVAIL;

			goto error;
		} else if (count == 0) {
			/*
			 * We can return ENOENT earlier than when register the
			 * kprobe.
			 */
			trace_probe_log_err(0, BAD_PROBE_ADDR);
			ret = -ENOENT;

			goto error;
		}
	}

	trace_probe_log_set_index(0);
	if (event) {
		ret = traceprobe_parse_event_name(&event, &group, gbuf,
@@ -1695,6 +1739,7 @@ static int unregister_kprobe_event(struct trace_kprobe *tk)
}

#ifdef CONFIG_PERF_EVENTS

/* create a trace_kprobe, but don't add it to global lists */
struct trace_event_call *
create_local_trace_kprobe(char *func, void *addr, unsigned long offs,
@@ -1705,6 +1750,24 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs,
	int ret;
	char *event;

	if (func) {
		unsigned int count;

		count = number_of_same_symbols(func);
		if (count > 1)
			/*
			 * Users should use addr to remove the ambiguity of
			 * using func only.
			 */
			return ERR_PTR(-EADDRNOTAVAIL);
		else if (count == 0)
			/*
			 * We can return ENOENT earlier than when register the
			 * kprobe.
			 */
			return ERR_PTR(-ENOENT);
	}

	/*
	 * local trace_kprobes are not added to dyn_event, so they are never
	 * searched in find_trace_kprobe(). Therefore, there is no concern of
+1 −0
Original line number Diff line number Diff line
@@ -450,6 +450,7 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call,
	C(BAD_MAXACT,		"Invalid maxactive number"),		\
	C(MAXACT_TOO_BIG,	"Maxactive is too big"),		\
	C(BAD_PROBE_ADDR,	"Invalid probed address or symbol"),	\
	C(NON_UNIQ_SYMBOL,	"The symbol is not unique"),		\
	C(BAD_RETPROBE,		"Retprobe address must be an function entry"), \
	C(NO_TRACEPOINT,	"Tracepoint is not found"),		\
	C(BAD_ADDR_SUFFIX,	"Invalid probed address suffix"), \
+13 −0
Original line number Diff line number Diff line
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: Test failure of registering kprobe on non unique symbol
# requires: kprobe_events

SYMBOL='name_show'

# We skip this test on kernel where SYMBOL is unique or does not exist.
if [ "$(grep -c -E "[[:alnum:]]+ t ${SYMBOL}" /proc/kallsyms)" -le '1' ]; then
	exit_unsupported
fi

! echo "p:test_non_unique ${SYMBOL}" > kprobe_events