From: ard.biesheuvel@linaro.org (Ard Biesheuvel)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC/PoC PATCH 3/3] arm64: enable ROP protection by clearing SP bit #55 across function returns
Date: Thu, 2 Aug 2018 15:21:32 +0200 [thread overview]
Message-ID: <20180802132133.23999-4-ard.biesheuvel@linaro.org> (raw)
In-Reply-To: <20180802132133.23999-1-ard.biesheuvel@linaro.org>
ROP attacks rely on a large supply of so-called 'gadgets', which are
(in this context) short sequences of instructions ending in a stack
pop and a return instruction. By exploiting a stack overflow to create
a specially crafted stack frame, each gadget jumps to the next by
popping off the next gadget's address as a fake return address,
allowing non-trivial 'programs' to be executed by piecing together
a large number of such gadgets.
This attack vector relies heavily on the ability to jump to arbitrary
places in the code. If we could limit where a function could return to,
it is much more difficult to obtain critical mass in terms of a gadget
collection that allows arbitrary attacks to be mounted.
So let's try and do so by clearing bit #55 in the stack pointer register
before returning from a function, and setting it again right after a
'bl' or 'blr' instruction. That way, jumping to arbitrary places in the
code and popping the next gadget's address becomes a lot more complicated,
since the stack pointer will not be valid after a function return until
the 'reset' sequence is executed (or after an exception is taken).
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/Kconfig | 10 ++++++++++
arch/arm64/include/asm/assembler.h | 9 +++++++++
arch/arm64/kernel/entry.S | 18 ++++++++++++++++++
3 files changed, 37 insertions(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 42c090cf0292..4562af0250b9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1011,6 +1011,16 @@ config ARM64_SW_TTBR0_PAN
zeroed area and reserved ASID. The user access routines
restore the valid TTBR0_EL1 temporarily.
+config ARM64_ROP_SHIELD
+ bool "Enable basic ROP protection through the stack pointer sign bit"
+ depends on GCC_PLUGINS && VMAP_STACK
+ select GCC_PLUGIN_ARM64_ROP_SHIELD
+ help
+ Enable protection against ROP attacks by clearing bit #55 in the
+ stack pointer register across a function return.
+
+ If paranoid, say Y here. If unsure, say N.
+
menu "ARMv8.1 architectural features"
config ARM64_HW_AFDBM
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 346ada4de48a..95d3ec98eb58 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -701,12 +701,21 @@ USER(\label, ic ivau, \tmp2) // invalidate I line PoU
.Lyield_out_\@ :
.endm
+ .macro unclobber_sp, tmp
+#ifdef CONFIG_ARM64_ROP_SHIELD
+ mov \tmp, sp
+ orr sp, \tmp, #(1 << 55)
+#endif
+ .endm
+
.macro bl_c, target
bl \target
+ unclobber_sp x30
.endm
.macro blr_c, reg
blr \reg
+ unclobber_sp x30
.endm
#endif /* __ASM_ASSEMBLER_H */
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index eba5b6b528ea..2adebca74f11 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -95,6 +95,9 @@ alternative_else_nop_endif
*/
add sp, sp, x0 // sp' = sp + x0
sub x0, sp, x0 // x0' = sp' - x0 = (sp + x0) - x0 = sp
+#ifdef CONFIG_ARM64_ROP_SHIELD
+ tbz x0, #55, 1f
+#endif
tbnz x0, #THREAD_SHIFT, 0f
sub x0, sp, x0 // x0'' = sp' - x0' = (sp + x0) - sp = x0
sub sp, sp, x0 // sp'' = sp' - x0 = (sp + x0) - x0 = sp
@@ -129,6 +132,21 @@ alternative_else_nop_endif
/* We were already on the overflow stack. Restore sp/x0 and carry on. */
sub sp, sp, x0
mrs x0, tpidrro_el0
+ b el\()\el\()_\label
+
+#ifdef CONFIG_ARM64_ROP_SHIELD
+1: /*
+ * We have to do a little dance here to set bit 55 in the stack
+ * pointer register without clobbering anything else.
+ */
+ orr x0, x0, #(1 << 55)
+ str x1, [x0]
+ mov x1, sp
+ mov sp, x0
+ and x0, x0, #~(1 << 55)
+ sub x0, x1, x0
+ ldr x1, [sp]
+#endif
#endif
b el\()\el\()_\label
.endm
--
2.18.0
next prev parent reply other threads:[~2018-08-02 13:21 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-02 13:21 [RFC/PoC PATCH 0/3] arm64: basic ROP mitigation Ard Biesheuvel
2018-08-02 13:21 ` [RFC/PoC PATCH 1/3] arm64: use wrapper macro for bl/blx instructions from asm code Ard Biesheuvel
2018-08-02 13:21 ` [RFC/PoC PATCH 2/3] gcc: plugins: add ROP shield plugin for arm64 Ard Biesheuvel
2018-08-02 13:21 ` Ard Biesheuvel [this message]
2018-08-06 10:07 ` [RFC/PoC PATCH 0/3] arm64: basic ROP mitigation Florian Weimer
2018-08-06 10:31 ` Ard Biesheuvel
2018-08-06 13:55 ` Robin Murphy
2018-08-06 14:04 ` Ard Biesheuvel
2018-08-06 15:20 ` Ard Biesheuvel
2018-08-06 15:38 ` Robin Murphy
2018-08-06 15:50 ` Ard Biesheuvel
2018-08-06 16:04 ` Ard Biesheuvel
2018-08-06 17:45 ` Robin Murphy
2018-08-06 18:49 ` Kees Cook
2018-08-06 19:35 ` Ard Biesheuvel
2018-08-06 19:50 ` Kees Cook
2018-08-06 19:54 ` Ard Biesheuvel
[not found] ` <CAN+XpFQCO1nr5tQ4oyPPaSfvnQSvwx-=JCtba2xJXrEN+6=LZg@mail.gmail.com>
2018-08-07 9:21 ` Ard Biesheuvel
2018-08-08 16:09 ` Mark Brand
2018-08-08 22:02 ` Kees Cook
2018-08-18 1:27 ` Laura Abbott
2018-08-20 6:30 ` Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180802132133.23999-4-ard.biesheuvel@linaro.org \
--to=ard.biesheuvel@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).