lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:   Wed,  9 Sep 2020 12:47:43 +0300
From:   Alexander Shishkin <alexander.shishkin@...ux.intel.com>
To:     Peter Zijlstra <a.p.zijlstra@...llo.nl>,
        Arnaldo Carvalho de Melo <acme@...hat.com>
Cc:     Ingo Molnar <mingo@...hat.com>, linux-kernel@...r.kernel.org,
        Jiri Olsa <jolsa@...nel.org>,
        Mathieu Poirier <mathieu.poirier@...aro.org>,
        adrian.hunter@...el.com,
        Alexander Shishkin <alexander.shishkin@...ux.intel.com>
Subject: [PATCH] perf: Turn kernel address filters into linear address filters

One thing that the address filters can't do at the moment is cover
anonymous mappings. Apparently, there is code out there that generates
executable code in anonymous mappings and executes it in place. And at
the moment we only allow file-based address filters for userspace.

The easiest way to do this is to repurpose the kernel filters and allow
those to be used on userspace addresses. The Intel PT driver at the moment
does enforce that non-file-based filters are only used with kernel
addresses, so that needs to be corrected. The Coresight ETM driver doesn't
enforce that, so no changes needed there.

No tooling changes required, either.

Signed-off-by: Alexander Shishkin <alexander.shishkin@...ux.intel.com>
---
 arch/x86/events/intel/pt.c | 13 -------------
 kernel/events/core.c       | 22 ++++++++++------------
 2 files changed, 10 insertions(+), 25 deletions(-)

diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index e94af4a54d0d..2d981dbaac1b 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -1347,11 +1347,6 @@ static void pt_addr_filters_fini(struct perf_event *event)
 	event->hw.addr_filters = NULL;
 }
 
-static inline bool valid_kernel_ip(unsigned long ip)
-{
-	return virt_addr_valid(ip) && kernel_ip(ip);
-}
-
 static int pt_event_addr_filters_validate(struct list_head *filters)
 {
 	struct perf_addr_filter *filter;
@@ -1366,14 +1361,6 @@ static int pt_event_addr_filters_validate(struct list_head *filters)
 		    filter->action == PERF_ADDR_FILTER_ACTION_START)
 			return -EOPNOTSUPP;
 
-		if (!filter->path.dentry) {
-			if (!valid_kernel_ip(filter->offset))
-				return -EINVAL;
-
-			if (!valid_kernel_ip(filter->offset + filter->size))
-				return -EINVAL;
-		}
-
 		if (++range > intel_pt_validate_hw_cap(PT_CAP_num_address_ranges))
 			return -EOPNOTSUPP;
 	}
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 57efe3b21e29..8579654d3fc7 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -9989,9 +9989,9 @@ enum {
 	IF_ACT_START,
 	IF_ACT_STOP,
 	IF_SRC_FILE,
-	IF_SRC_KERNEL,
+	IF_SRC_LINEAR,
 	IF_SRC_FILEADDR,
-	IF_SRC_KERNELADDR,
+	IF_SRC_LINEARADDR,
 };
 
 enum {
@@ -10005,9 +10005,9 @@ static const match_table_t if_tokens = {
 	{ IF_ACT_START,		"start" },
 	{ IF_ACT_STOP,		"stop" },
 	{ IF_SRC_FILE,		"%u/%u@%s" },
-	{ IF_SRC_KERNEL,	"%u/%u" },
+	{ IF_SRC_LINEAR,	"%u/%u" },
 	{ IF_SRC_FILEADDR,	"%u@%s" },
-	{ IF_SRC_KERNELADDR,	"%u" },
+	{ IF_SRC_LINEARADDR,	"%u" },
 	{ IF_ACT_NONE,		NULL },
 };
 
@@ -10022,7 +10022,7 @@ perf_event_parse_addr_filter(struct perf_event *event, char *fstr,
 	char *start, *orig, *filename = NULL;
 	substring_t args[MAX_OPT_ARGS];
 	int state = IF_STATE_ACTION, token;
-	unsigned int kernel = 0;
+	unsigned int linear = 0;
 	int ret = -EINVAL;
 
 	orig = fstr = kstrdup(fstr, GFP_KERNEL);
@@ -10059,9 +10059,9 @@ perf_event_parse_addr_filter(struct perf_event *event, char *fstr,
 			state = IF_STATE_SOURCE;
 			break;
 
-		case IF_SRC_KERNELADDR:
-		case IF_SRC_KERNEL:
-			kernel = 1;
+		case IF_SRC_LINEARADDR:
+		case IF_SRC_LINEAR:
+			linear = 1;
 			/* fall through */
 
 		case IF_SRC_FILEADDR:
@@ -10074,7 +10074,7 @@ perf_event_parse_addr_filter(struct perf_event *event, char *fstr,
 			if (ret)
 				goto fail;
 
-			if (token == IF_SRC_KERNEL || token == IF_SRC_FILE) {
+			if (token == IF_SRC_LINEAR || token == IF_SRC_FILE) {
 				*args[1].to = 0;
 				ret = kstrtoul(args[1].from, 0, &filter->size);
 				if (ret)
@@ -10105,8 +10105,6 @@ perf_event_parse_addr_filter(struct perf_event *event, char *fstr,
 		 */
 		if (state == IF_STATE_END) {
 			ret = -EINVAL;
-			if (kernel && event->attr.exclude_kernel)
-				goto fail;
 
 			/*
 			 * ACTION "filter" must have a non-zero length region
@@ -10116,7 +10114,7 @@ perf_event_parse_addr_filter(struct perf_event *event, char *fstr,
 			    !filter->size)
 				goto fail;
 
-			if (!kernel) {
+			if (!linear) {
 				if (!filename)
 					goto fail;
 
-- 
2.28.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ