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]
Message-Id: <20181005081333.15018-3-ard.biesheuvel@linaro.org>
Date:   Fri,  5 Oct 2018 10:13:26 +0200
From:   Ard Biesheuvel <ard.biesheuvel@...aro.org>
To:     linux-kernel@...r.kernel.org
Cc:     Ard Biesheuvel <ard.biesheuvel@...aro.org>,
        "Jason A . Donenfeld" <Jason@...c4.com>,
        Eric Biggers <ebiggers@...nel.org>,
        Samuel Neves <sneves@....uc.pt>,
        Andy Lutomirski <luto@...nel.org>,
        Arnd Bergmann <arnd@...db.de>,
        Herbert Xu <herbert@...dor.apana.org.au>,
        "David S. Miller" <davem@...emloft.net>,
        Catalin Marinas <catalin.marinas@....com>,
        Will Deacon <will.deacon@....com>,
        Benjamin Herrenschmidt <benh@...nel.crashing.org>,
        Paul Mackerras <paulus@...ba.org>,
        Michael Ellerman <mpe@...erman.id.au>,
        Thomas Gleixner <tglx@...utronix.de>,
        Ingo Molnar <mingo@...hat.com>,
        Kees Cook <keescook@...omium.org>,
        "Martin K. Petersen" <martin.petersen@...cle.com>,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        Andrew Morton <akpm@...ux-foundation.org>,
        Richard Weinberger <richard@....at>,
        Peter Zijlstra <peterz@...radead.org>,
        linux-crypto@...r.kernel.org, linux-arm-kernel@...ts.infradead.org,
        linuxppc-dev@...ts.ozlabs.org
Subject: [RFC PATCH 2/9] arm64: kernel: add arch support for patchable function pointers

Implement arm64 support for patchable function pointers by emitting
them as branch instructions (and a couple of NOPs in case the new
target is out of range of a normal branch instruction.)

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@...aro.org>
---
 arch/arm64/Kconfig           |  1 +
 arch/arm64/include/asm/ffp.h | 35 ++++++++++++++++++++
 arch/arm64/kernel/insn.c     | 22 ++++++++++++
 3 files changed, 58 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 1b1a0e95c751..db8c9e51c56d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -102,6 +102,7 @@ config ARM64
 	select HAVE_ALIGNED_STRUCT_PAGE if SLUB
 	select HAVE_ARCH_AUDITSYSCALL
 	select HAVE_ARCH_BITREVERSE
+	select HAVE_ARCH_FFP
 	select HAVE_ARCH_HUGE_VMAP
 	select HAVE_ARCH_JUMP_LABEL
 	select HAVE_ARCH_KASAN if !(ARM64_16K_PAGES && ARM64_VA_BITS_48)
diff --git a/arch/arm64/include/asm/ffp.h b/arch/arm64/include/asm/ffp.h
new file mode 100644
index 000000000000..678dc1262218
--- /dev/null
+++ b/arch/arm64/include/asm/ffp.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_FFP_H
+#define __ASM_FFP_H
+
+struct ffp {
+	u32	insn[5];
+	u32	def_branch;
+};
+
+#define DECLARE_FFP(_fn, _def)						\
+	extern typeof(_def) _fn;					\
+	extern struct ffp const __ffp_ ## _fn
+
+#define DEFINE_FFP(_fn, _def)						\
+	DECLARE_FFP(_fn, _def);						\
+	asm("	.pushsection	\".text\", \"ax\", %progbits	\n"	\
+	    "	.align		3				\n"	\
+	    "	.globl		" #_fn "			\n"	\
+	    "	.globl		__ffp_" #_fn "			\n"	\
+	    #_fn " :						\n"	\
+	    "__ffp_" #_fn " :					\n"	\
+	    "		b	" #_def "			\n"	\
+	    "		nop					\n"	\
+	    "		nop					\n"	\
+	    "		nop					\n"	\
+	    "		nop					\n"	\
+	    "		b	" #_def "			\n"	\
+	    "	.popsection					\n");	\
+	EXPORT_SYMBOL(__ffp_ ## _fn)
+
+extern void ffp_set_target(const struct ffp *m, void *new_fn);
+extern void ffp_reset_target(const struct ffp *m);
+
+#endif
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
index 2b3413549734..a2ed547fd171 100644
--- a/arch/arm64/kernel/insn.c
+++ b/arch/arm64/kernel/insn.c
@@ -30,6 +30,7 @@
 #include <asm/cacheflush.h>
 #include <asm/debug-monitors.h>
 #include <asm/fixmap.h>
+#include <asm/ffp.h>
 #include <asm/insn.h>
 #include <asm/kprobes.h>
 
@@ -1603,3 +1604,24 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
 	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
 	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm);
 }
+
+void ffp_set_target(const struct ffp *m, void *new_fn)
+{
+	u32 branch = aarch64_insn_gen_branch_imm((u64)m, (u64)new_fn,
+						 AARCH64_INSN_BRANCH_NOLINK);
+
+	if (branch == AARCH64_BREAK_FAULT) {
+		/* TODO out of range - use a PLT sequence instead */
+	} else {
+		aarch64_insn_patch_text((void *[]){ (void *)m }, &branch, 1);
+	}
+}
+EXPORT_SYMBOL(ffp_set_target);
+
+void ffp_reset_target(const struct ffp *m)
+{
+	u32 branch = le32_to_cpu(m->def_branch);
+
+	aarch64_insn_patch_text((void *[]){ (void *)m }, &branch, 1);
+}
+EXPORT_SYMBOL(ffp_reset_target);
-- 
2.11.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ