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, 28 Nov 2022 13:44:57 +1100
From:   Benjamin Gray <bgray@...ux.ibm.com>
To:     linuxppc-dev@...ts.ozlabs.org
Cc:     ajd@...ux.ibm.com, ruscur@...sell.cc, linux-kernel@...r.kernel.org,
        linux-hardening@...r.kernel.org, cmr@...escreens.de,
        Benjamin Gray <bgray@...ux.ibm.com>
Subject: [RFC PATCH 12/13] selftests/powerpc: Add DEXCR status utility lsdexcr

Add a utility 'lsdexcr' to print the current DEXCR status. Useful for
quickly checking the status when debugging test failures, using the
sysctl interfaces manually, or just wanting to check it.

Example output:

          Requested: 84000000 (SBHE, NPHIE)
Hypervisor enforced: 00000000
          Effective: 84000000 (SBHE, NPHIE)

        SBHE * (0): set, prctl editable  	(Speculative branch hint enable)
      IBRTPD   (3): clear, prctl editable  	(Indirect branch recurrent target prediction disable)
       SRAPD   (4): clear, prctl editable  	(Subroutine return address prediction disable)
       NPHIE * (5): set  	(Non-privileged hash instruction enable)

Global SBHE override: 1 (set)

Signed-off-by: Benjamin Gray <bgray@...ux.ibm.com>
---
 .../selftests/powerpc/dexcr/.gitignore        |   1 +
 .../testing/selftests/powerpc/dexcr/Makefile  |   2 +
 .../testing/selftests/powerpc/dexcr/lsdexcr.c | 178 ++++++++++++++++++
 3 files changed, 181 insertions(+)
 create mode 100644 tools/testing/selftests/powerpc/dexcr/lsdexcr.c

diff --git a/tools/testing/selftests/powerpc/dexcr/.gitignore b/tools/testing/selftests/powerpc/dexcr/.gitignore
index 035a1fcd8fb3..7dd2fad93732 100644
--- a/tools/testing/selftests/powerpc/dexcr/.gitignore
+++ b/tools/testing/selftests/powerpc/dexcr/.gitignore
@@ -1,2 +1,3 @@
 dexcr_test
 hashchk_user
+lsdexcr
diff --git a/tools/testing/selftests/powerpc/dexcr/Makefile b/tools/testing/selftests/powerpc/dexcr/Makefile
index 9814e72a4afa..8cb732cda7e7 100644
--- a/tools/testing/selftests/powerpc/dexcr/Makefile
+++ b/tools/testing/selftests/powerpc/dexcr/Makefile
@@ -1,4 +1,5 @@
 TEST_GEN_PROGS := dexcr_test hashchk_test
+TEST_GEN_FILES := lsdexcr
 
 TEST_FILES := settings
 top_srcdir = ../../../../..
@@ -7,3 +8,4 @@ include ../../lib.mk
 HASHCHK_TEST_CFLAGS = -no-pie $(call cc-option,-mno-rop-protect)
 
 $(TEST_GEN_PROGS): ../harness.c ../utils.c ./dexcr.c ./cap.c
+$(TEST_GEN_FILES): ../utils.c ./dexcr.c
diff --git a/tools/testing/selftests/powerpc/dexcr/lsdexcr.c b/tools/testing/selftests/powerpc/dexcr/lsdexcr.c
new file mode 100644
index 000000000000..c9f0035f8e2e
--- /dev/null
+++ b/tools/testing/selftests/powerpc/dexcr/lsdexcr.c
@@ -0,0 +1,178 @@
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/prctl.h>
+
+#include "dexcr.h"
+#include "utils.h"
+
+static unsigned int requested;
+static unsigned int enforced;
+static unsigned int effective;
+
+struct dexcr_aspect {
+	const char *name;
+	const char *desc;
+	unsigned int index;
+	unsigned long pr_val;
+};
+
+static const struct dexcr_aspect aspects[] = {
+	{
+		.name = "SBHE",
+		.desc = "Speculative branch hint enable",
+		.index = 0,
+		.pr_val = PR_PPC_DEXCR_SBHE,
+	},
+	{
+		.name = "IBRTPD",
+		.desc = "Indirect branch recurrent target prediction disable",
+		.index = 3,
+		.pr_val = PR_PPC_DEXCR_IBRTPD,
+	},
+	{
+		.name = "SRAPD",
+		.desc = "Subroutine return address prediction disable",
+		.index = 4,
+		.pr_val = PR_PPC_DEXCR_SRAPD,
+	},
+	{
+		.name = "NPHIE",
+		.desc = "Non-privileged hash instruction enable",
+		.index = 5,
+		.pr_val = PR_PPC_DEXCR_NPHIE,
+	},
+};
+
+#define NUM_ASPECTS (sizeof(aspects) / sizeof(struct dexcr_aspect))
+
+static void print_list(const char *list[], size_t len)
+{
+	for (size_t i = 0; i < len; i++) {
+		printf("%s", list[i]);
+		if (i + 1 < len)
+			printf(", ");
+	}
+}
+
+static void print_dexcr(char *name, unsigned int bits)
+{
+	const char *enabled_aspects[32] = {NULL};
+	size_t j = 0;
+
+	printf("%s: %08x", name, bits);
+
+	if (bits == 0) {
+		printf("\n");
+		return;
+	}
+
+	for (size_t i = 0; i < NUM_ASPECTS; i++) {
+		unsigned int mask = pr_aspect_to_dexcr_mask(aspects[i].pr_val);
+		if (bits & mask) {
+			enabled_aspects[j++] = aspects[i].name;
+			bits &= ~mask;
+		}
+	}
+
+	if (bits)
+		enabled_aspects[j++] = "unknown";
+
+	printf(" (");
+	print_list(enabled_aspects, j);
+	printf(")\n");
+}
+
+static void print_aspect(const struct dexcr_aspect *aspect)
+{
+	const char *attributes[32] = {NULL};
+	size_t j = 0;
+	unsigned long mask;
+	int pr_status;
+
+	/* Kernel-independent info about aspect */
+	mask = pr_aspect_to_dexcr_mask(aspect->pr_val);
+	if (requested & mask)
+		attributes[j++] = "set";
+	if (enforced & mask)
+		attributes[j++] = "hypervisor enforced";
+	if (!(effective & mask))
+		attributes[j++] = "clear";
+
+	/* Kernel understanding of the aspect */
+	pr_status = prctl(PR_PPC_GET_DEXCR, aspect->pr_val, 0, 0, 0);
+	if (pr_status == -1) {
+		switch (errno) {
+		case ENODEV:
+			attributes[j++] = "aspect not present";
+			break;
+		case EINVAL:
+			attributes[j++] = "unrecognised aspect";
+			break;
+		default:
+			attributes[j++] = "unknown kernel error";
+			break;
+		}
+	} else {
+		if (pr_status & PR_PPC_DEXCR_SET_ASPECT)
+			attributes[j++] = "prctl set";
+		if (pr_status & PR_PPC_DEXCR_FORCE_SET_ASPECT)
+			attributes[j++] = "prctl force set";
+		if (pr_status & PR_PPC_DEXCR_CLEAR_ASPECT)
+			attributes[j++] = "prctl clear";
+		if (pr_status & PR_PPC_DEXCR_PRCTL)
+			attributes[j++] = "prctl editable";
+	}
+
+	printf("%12s %c (%d): ", aspect->name, effective & mask ? '*' : ' ', aspect->index);
+	print_list(attributes, j);
+	printf("  \t(%s)\n", aspect->desc);
+}
+
+static void print_overrides(void) {
+	long sbhe;
+	int err;
+
+	printf("Global SBHE override: ");
+	if ((err = read_long(SYSCTL_DEXCR_SBHE, &sbhe, 10))) {
+		printf("error reading " SYSCTL_DEXCR_SBHE ": %d (%s)\n", err, strerror(err));
+	} else {
+		const char *meaning;
+		switch (sbhe) {
+		case -1:
+			meaning = "default";
+			break;
+		case 0:
+			meaning = "clear";
+			break;
+		case 1:
+			meaning = "set";
+			break;
+		default:
+			meaning = "unknown";
+		}
+
+		printf("%ld (%s)\n", sbhe, meaning);
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	requested = get_dexcr(UDEXCR);
+	enforced = get_dexcr(ENFORCED);
+	effective = requested | enforced;
+
+	print_dexcr("          Requested", requested);
+	print_dexcr("Hypervisor enforced", enforced);
+	print_dexcr("          Effective", effective);
+	printf("\n");
+
+	for (size_t i = 0; i < NUM_ASPECTS; i++)
+		print_aspect(&aspects[i]);
+	printf("\n");
+
+	print_overrides();
+
+	return 0;
+}
-- 
2.38.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ