git: e340882d3e49 - main - arm64: Add BTI landing pads to assembly functions
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 10 Oct 2023 09:53:13 UTC
The branch main has been updated by andrew:
URL: https://cgit.FreeBSD.org/src/commit/?id=e340882d3e49a98aa39b13041a2bf714c30dccdf
commit e340882d3e49a98aa39b13041a2bf714c30dccdf
Author: Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2023-10-03 08:52:02 +0000
Commit: Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2023-10-10 09:52:16 +0000
arm64: Add BTI landing pads to assembly functions
When we enable BTI iboth the first instruction in a function that could
be called indirectly, and a branch within a function need a valid
landing pad instruction.
There are three options for these instructions:
1. A breakpoint instruction
2. A pointer authentication PACIASP/PACIBSP
3. A BTI instruction
Option 1 will raise a breakpoint exception so isn't useable in either
cases. Option 2 could be used in some function entry cases, but needs
to be paired with an authentication instruction, and is normally only
used in non-leaf functions we can't use it in this case. This leaves
option 3.
There are four variants of the instruction, the C variant is used on
function entry and the J variant is for jumping within a function.
There is also a JC that works with both and one with no target that
works with neither.
Reviewed by: markj
Sponsored by: Arm Ltd
Sponsored by: The FreeBSD Foundation (earlier version)
Differential Revision: https://reviews.freebsd.org/D42078
---
sys/arm64/arm64/locore.S | 4 ++++
sys/arm64/include/asm.h | 30 +++++++++++++++++++++++++++++-
2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S
index bc2a84c404ab..f741bccf598a 100644
--- a/sys/arm64/arm64/locore.S
+++ b/sys/arm64/arm64/locore.S
@@ -107,6 +107,8 @@ ENTRY(_start)
br x15
virtdone:
+ BTI_J
+
/* Set up the stack */
adrp x25, initstack_end
add x25, x25, :lo12:initstack_end
@@ -223,6 +225,8 @@ ENTRY(mpentry)
br x15
mp_virtdone:
+ BTI_J
+
/* Start using the AP boot stack */
ldr x4, =bootstack
ldr x4, [x4]
diff --git a/sys/arm64/include/asm.h b/sys/arm64/include/asm.h
index 5c1f874366fd..6ebfca6eaf0c 100644
--- a/sys/arm64/include/asm.h
+++ b/sys/arm64/include/asm.h
@@ -48,7 +48,7 @@
#define LENTRY(sym) \
.text; .align 2; .type sym,#function; sym: \
- .cfi_startproc; DTRACE_NOP
+ .cfi_startproc; BTI_C; DTRACE_NOP
#define ENTRY(sym) \
.globl sym; LENTRY(sym)
#define EENTRY(sym) \
@@ -114,6 +114,34 @@
dsb sy; \
isb
+/*
+ * When a CPU that implements FEAT_BTI uses a BR/BLR instruction (or the
+ * pointer authentication variants, e.g. BLRAA) and the target location
+ * has the GP attribute in its page table, then the target of the BR/BLR
+ * needs to be a valid BTI landing pad.
+ *
+ * BTI_C should be used at the start of a function and is used in the
+ * ENTRY macro. It can be replaced by PACIASP or PACIBSP, however these
+ * also need an appropriate authenticate instruction before returning.
+ *
+ * BTI_J should be used as the target instruction when branching with a
+ * BR instruction within a function.
+ *
+ * When using a BR to branch to a new function, e.g. a tail call, then
+ * the target register should be x16 or x17 so it is compatible with
+ * the BRI_C instruction.
+ *
+ * As these instructions are in the hint space they are a NOP when
+ * the CPU doesn't implement FEAT_BTI so are safe to use.
+ */
+#ifdef __ARM_FEATURE_BTI_DEFAULT
+#define BTI_C hint #34
+#define BTI_J hint #36
+#else
+#define BTI_C
+#define BTI_J
+#endif
+
#endif /* _MACHINE_ASM_H_ */
#endif /* !__arm__ */