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>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon,  4 Jul 2022 15:53:28 +0100
From:   Andrew Kilroy <andrew.kilroy@....com>
To:     linux-kernel@...r.kernel.org, linux-perf-users@...r.kernel.org,
        acme@...nel.org
Cc:     Andrew Kilroy <andrew.kilroy@....com>,
        Mark Rutland <mark.rutland@....com>,
        Alexander Shishkin <alexander.shishkin@...ux.intel.com>,
        Jiri Olsa <jolsa@...nel.org>,
        Namhyung Kim <namhyung@...nel.org>,
        Martin KaFai Lau <kafai@...com>,
        Song Liu <songliubraving@...com>, Yonghong Song <yhs@...com>,
        John Fastabend <john.fastabend@...il.com>,
        KP Singh <kpsingh@...nel.org>, Tom Rix <trix@...hat.com>,
        linux-arm-kernel@...ts.infradead.org, netdev@...r.kernel.org,
        bpf@...r.kernel.org, llvm@...ts.linux.dev
Subject: [PATCH 4/8] perf tools: arm64: Read ptrauth data from kernel

This patch alters the userspace perf program to request the
pointer authentication code masks using the PERF_SAMPLE_ARCH_1 sample
field and write the data to perf.data file.

A subsequent commit will make use of the masks in the data file to do
the unwinding.

Signed-off-by: Andrew Kilroy <andrew.kilroy@....com>
---
 tools/perf/tests/sample-parsing.c |  2 +-
 tools/perf/util/event.h           |  8 ++++++
 tools/perf/util/evsel.c           | 45 +++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
index 07f2411b0ad4..dd78ca279c01 100644
--- a/tools/perf/tests/sample-parsing.c
+++ b/tools/perf/tests/sample-parsing.c
@@ -381,7 +381,7 @@ static int test__sample_parsing(struct test_suite *test __maybe_unused, int subt
 	 * were added.  Please actually update the test rather than just change
 	 * the condition below.
 	 */
-	if (PERF_SAMPLE_MAX > PERF_SAMPLE_WEIGHT_STRUCT << 1) {
+	if (PERF_SAMPLE_MAX > PERF_SAMPLE_ARCH_1 << 1) {
 		pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
 		return -1;
 	}
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index cdd72e05fd28..b99fc81dd37e 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -128,6 +128,13 @@ struct aux_sample {
 	void *data;
 };
 
+
+struct ptrauth_info {
+	u64 enabled_keys;  // arm64 ptrauth is in use if this is non-zero.
+	u64 insn_mask;
+	u64 data_mask;
+};
+
 struct perf_sample {
 	u64 ip;
 	u32 pid, tid;
@@ -163,6 +170,7 @@ struct perf_sample {
 	struct stack_dump user_stack;
 	struct sample_read read;
 	struct aux_sample aux_sample;
+	struct ptrauth_info ptrauth;
 };
 
 #define PERF_MEM_DATA_SRC_NONE \
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 25d8f804f49a..4627a68a7797 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -887,8 +887,22 @@ static void __evsel__config_callchain(struct evsel *evsel, struct record_opts *o
 				    "Falling back to framepointers.\n");
 	}
 
+#if defined(__aarch64__)
+	/*
+	 * We need to set ARM64_PTRAUTH in FP mode so that b9f6fbb3b2c2 ("perf arm64: Inject missing
+	 * frames when using 'perf record --call-graph=fp'") continues to work in the presence of
+	 * PACs.
+	 */
+	if (param->record_mode == CALLCHAIN_FP)
+		evsel__set_sample_bit(evsel, ARM64_PTRAUTH);
+
+#endif
+
 	if (param->record_mode == CALLCHAIN_DWARF) {
 		if (!function) {
+#if defined(__aarch64__)
+			evsel__set_sample_bit(evsel, ARM64_PTRAUTH);
+#endif
 			evsel__set_sample_bit(evsel, REGS_USER);
 			evsel__set_sample_bit(evsel, STACK_USER);
 			if (opts->sample_user_regs && DWARF_MINIMAL_REGS != PERF_REGS_MASK) {
@@ -2344,6 +2358,17 @@ u64 evsel__bitfield_swap_branch_flags(u64 value)
 	return new_val;
 }
 
+/*
+ * To return the normalised arch that is recorded in a perf.data file
+ */
+static const char *recorded_normalized_arch(struct evsel *evsel)
+{
+	if (evsel && evsel->evlist && evsel->evlist->env)
+		return perf_env__arch(evsel->evlist->env);
+	else
+		return NULL;
+}
+
 int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
 			struct perf_sample *data)
 {
@@ -2681,6 +2706,26 @@ int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
 		array = (void *)array + sz;
 	}
 
+	if (type & PERF_SAMPLE_ARCH_1) {
+		const char *normlzd_arch = recorded_normalized_arch(evsel);
+
+		if (normlzd_arch)
+			pr_debug4("PERF_SAMPLE_ARCH_1 is on, detected recorded arch as %s\n", normlzd_arch);
+		else
+			pr_debug4("PERF_SAMPLE_ARCH_1 is on, but arch not detected\n");
+
+		if (normlzd_arch && strcmp(normlzd_arch, "arm64") == 0) {
+			OVERFLOW_CHECK(array, 3 * sizeof(u64), max_size);
+
+			data->ptrauth.enabled_keys = *array;
+			array++;
+			data->ptrauth.insn_mask = *array;
+			array++;
+			data->ptrauth.data_mask = *array;
+			array++;
+		}
+	}
+
 	return 0;
 }
 
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ