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:	Fri, 21 Sep 2012 11:56:00 -0400
From:	Cyril Chemparathy <cyril@...com>
To:	<linux@....linux.org.uk>
CC:	<linux-arm-kernel@...ts.infradead.org>,
	<linux-kernel@...r.kernel.org>, <arnd@...db.de>,
	<catalin.marinas@....com>, <davidb@...eaurora.org>,
	<frank.rowand@...sony.com>, <hsweeten@...ionengravers.com>,
	<linus.walleij@...aro.org>, <marc.zyngier@....com>,
	<nico@...aro.org>, <paul.gortmaker@...driver.com>,
	<plagnioj@...osoft.com>, <rabin@....in>, <rmallon@...il.com>,
	<rob.herring@...xeda.com>, <sboyd@...eaurora.org>,
	<sjg@...omium.org>, <tglx@...utronix.de>, <tj@...nel.org>,
	<vincent.guittot@...aro.org>, <vitalya@...com>,
	<will.deacon@....com>, <grant.likely@...retlab.ca>,
	Cyril Chemparathy <cyril@...com>
Subject: [PATCH v3 RESEND 02/17] ARM: add self test for runtime patch mechanism

This patch adds basic sanity tests to ensure that the instruction patching
results in valid instruction encodings.  This is done by verifying the output
of the patch process against a vector of assembler generated instructions at
init time.

Signed-off-by: Cyril Chemparathy <cyril@...com>
---
 arch/arm/Kconfig                |   12 +++++++
 arch/arm/kernel/runtime-patch.c |   75 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 98a3a1a..5bfaa20 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -205,6 +205,18 @@ config ARM_PATCH_PHYS_VIRT
 	  this feature (eg, building a kernel for a single machine) and
 	  you need to shrink the kernel to the minimal size.
 
+config ARM_RUNTIME_PATCH_TEST
+	bool "Self test runtime patching mechanism" if ARM_RUNTIME_PATCH
+	default y
+	help
+	  Select this to enable init time self checking for the runtime kernel
+	  patching mechanism.  This enables an ISA specific set of tests that
+	  ensure that the instructions generated by the patch process are
+	  consistent with those generated by the assembler at compile time.
+
+	  Only disable this option if you need to shrink the kernel to the
+	  minimal size.
+
 config NEED_MACH_IO_H
 	bool
 	help
diff --git a/arch/arm/kernel/runtime-patch.c b/arch/arm/kernel/runtime-patch.c
index 28a6367..0be9ef3 100644
--- a/arch/arm/kernel/runtime-patch.c
+++ b/arch/arm/kernel/runtime-patch.c
@@ -168,6 +168,78 @@ static int apply_patch_imm8(const struct patch_info *p)
 	return 0;
 }
 
+#ifdef CONFIG_ARM_RUNTIME_PATCH_TEST
+
+struct patch_test_imm8 {
+	u16	imm;
+	u16	shift;
+	u32	insn;
+};
+
+static void __init __used __naked __patch_test_code_imm8(void)
+{
+	__asm__ __volatile__ (
+
+		/* a single test case */
+		"	.macro		test_one, imm, sft\n"
+		"	.hword		\\imm\n"
+		"	.hword		\\sft\n"
+		"	add		r1, r2, #(\\imm << \\sft)\n"
+		"	.endm\n"
+
+		/* a sequence of tests at 'inc' increments of shift */
+		"	.macro		test_seq, imm, sft, max, inc\n"
+		"	test_one	\\imm, \\sft\n"
+		"	.if		\\sft < \\max\n"
+		"	test_seq	\\imm, (\\sft + \\inc), \\max, \\inc\n"
+		"	.endif\n"
+		"	.endm\n"
+
+		/* an empty record to mark the end */
+		"	.macro		test_end\n"
+		"	.hword		0, 0\n"
+		"	.word		0\n"
+		"	.endm\n"
+
+		/* finally generate the test sequences */
+		"	test_seq	0x41, 0, 24, 1\n"
+		"	test_seq	0x81, 0, 24, 2\n"
+		"	test_end\n"
+		: : : "r1", "r2", "cc");
+}
+
+static void __init test_patch_imm8(void)
+{
+	u32 test_code_addr = (u32)(&__patch_test_code_imm8);
+	struct patch_test_imm8 *test = (void *)(test_code_addr & ~1);
+	u32 ninsn, insn, patched_insn;
+	int i, err;
+
+	insn = test[0].insn;
+	for (i = 0; test[i].insn; i++) {
+		err = do_patch_imm8(insn, test[i].imm << test[i].shift, &ninsn);
+		__patch_text(&patched_insn, ninsn);
+
+		if (err) {
+			pr_err("rtpatch imm8: failed at imm %x, shift %d\n",
+			       test[i].imm, test[i].shift);
+		} else if (patched_insn != test[i].insn) {
+			pr_err("rtpatch imm8: failed, need %x got %x\n",
+			       test[i].insn, patched_insn);
+		} else {
+			pr_debug("rtpatch imm8: imm %x, shift %d, %x -> %x\n",
+				 test[i].imm, test[i].shift, insn,
+				 patched_insn);
+		}
+	}
+}
+
+static void __init runtime_patch_test(void)
+{
+	test_patch_imm8();
+}
+#endif
+
 int runtime_patch(const void *table, unsigned size)
 {
 	const struct patch_info *p = table, *end = (table + size);
@@ -189,5 +261,8 @@ void __init runtime_patch_kernel(void)
 	const void *start = &__runtime_patch_table_begin;
 	const void *end   = &__runtime_patch_table_end;
 
+#ifdef CONFIG_ARM_RUNTIME_PATCH_TEST
+	runtime_patch_test();
+#endif
 	BUG_ON(runtime_patch(start, end - start));
 }
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ