Skip to content

Commit d278652

Browse files
committed
Merge branch 'for-next/bti' into for-next/core
Support for Branch Target Identification (BTI) in user and kernel (Mark Brown and others) * for-next/bti: (39 commits) arm64: vdso: Fix CFI directives in sigreturn trampoline arm64: vdso: Don't prefix sigreturn trampoline with a BTI C instruction arm64: bti: Fix support for userspace only BTI arm64: kconfig: Update and comment GCC version check for kernel BTI arm64: vdso: Map the vDSO text with guarded pages when built for BTI arm64: vdso: Force the vDSO to be linked as BTI when built for BTI arm64: vdso: Annotate for BTI arm64: asm: Provide a mechanism for generating ELF note for BTI arm64: bti: Provide Kconfig for kernel mode BTI arm64: mm: Mark executable text as guarded pages arm64: bpf: Annotate JITed code for BTI arm64: Set GP bit in kernel page tables to enable BTI for the kernel arm64: asm: Override SYM_FUNC_START when building the kernel with BTI arm64: bti: Support building kernel C code using BTI arm64: Document why we enable PAC support for leaf functions arm64: insn: Report PAC and BTI instructions as skippable arm64: insn: Don't assume unrecognized HINTs are skippable arm64: insn: Provide a better name for aarch64_insn_is_nop() arm64: insn: Add constants for new HINT instruction decode arm64: Disable old style assembly annotations ...
2 parents 342403b + a4eb355 commit d278652

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+963
-219
lines changed

Documentation/arm64/cpu-feature-registers.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ infrastructure:
176176
+------------------------------+---------+---------+
177177
| SSBS | [7-4] | y |
178178
+------------------------------+---------+---------+
179+
| BT | [3-0] | y |
180+
+------------------------------+---------+---------+
179181

180182

181183
4) MIDR_EL1 - Main ID Register

Documentation/arm64/elf_hwcaps.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,11 @@ HWCAP2_RNG
236236

237237
Functionality implied by ID_AA64ISAR0_EL1.RNDR == 0b0001.
238238

239+
HWCAP2_BTI
240+
241+
Functionality implied by ID_AA64PFR0_EL1.BT == 0b0001.
242+
243+
239244
4. Unused AT_HWCAP bits
240245
-----------------------
241246

Documentation/filesystems/proc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@ encoded manner. The codes are the following:
543543
hg huge page advise flag
544544
nh no huge page advise flag
545545
mg mergable advise flag
546+
bt - arm64 BTI guarded page
546547
== =======================================
547548

548549
Note that there is no guarantee that every flag and associated mnemonic will

arch/arm64/Kconfig

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ config ARM64
99
select ACPI_MCFG if (ACPI && PCI)
1010
select ACPI_SPCR_TABLE if ACPI
1111
select ACPI_PPTT if ACPI
12+
select ARCH_BINFMT_ELF_STATE
1213
select ARCH_HAS_DEBUG_VIRTUAL
1314
select ARCH_HAS_DEVMEM_IS_ALLOWED
1415
select ARCH_HAS_DMA_PREP_COHERENT
@@ -32,6 +33,7 @@ config ARM64
3233
select ARCH_HAS_SYSCALL_WRAPPER
3334
select ARCH_HAS_TEARDOWN_DMA_OPS if IOMMU_SUPPORT
3435
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
36+
select ARCH_HAVE_ELF_PROT
3537
select ARCH_HAVE_NMI_SAFE_CMPXCHG
3638
select ARCH_INLINE_READ_LOCK if !PREEMPTION
3739
select ARCH_INLINE_READ_LOCK_BH if !PREEMPTION
@@ -61,8 +63,10 @@ config ARM64
6163
select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE if !PREEMPTION
6264
select ARCH_KEEP_MEMBLOCK
6365
select ARCH_USE_CMPXCHG_LOCKREF
66+
select ARCH_USE_GNU_PROPERTY
6467
select ARCH_USE_QUEUED_RWLOCKS
6568
select ARCH_USE_QUEUED_SPINLOCKS
69+
select ARCH_USE_SYM_ANNOTATIONS
6670
select ARCH_SUPPORTS_MEMORY_FAILURE
6771
select ARCH_SUPPORTS_ATOMIC_RMW
6872
select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 && (GCC_VERSION >= 50000 || CC_IS_CLANG)
@@ -1584,6 +1588,48 @@ endmenu
15841588

15851589
menu "ARMv8.5 architectural features"
15861590

1591+
config ARM64_BTI
1592+
bool "Branch Target Identification support"
1593+
default y
1594+
help
1595+
Branch Target Identification (part of the ARMv8.5 Extensions)
1596+
provides a mechanism to limit the set of locations to which computed
1597+
branch instructions such as BR or BLR can jump.
1598+
1599+
To make use of BTI on CPUs that support it, say Y.
1600+
1601+
BTI is intended to provide complementary protection to other control
1602+
flow integrity protection mechanisms, such as the Pointer
1603+
authentication mechanism provided as part of the ARMv8.3 Extensions.
1604+
For this reason, it does not make sense to enable this option without
1605+
also enabling support for pointer authentication. Thus, when
1606+
enabling this option you should also select ARM64_PTR_AUTH=y.
1607+
1608+
Userspace binaries must also be specifically compiled to make use of
1609+
this mechanism. If you say N here or the hardware does not support
1610+
BTI, such binaries can still run, but you get no additional
1611+
enforcement of branch destinations.
1612+
1613+
config ARM64_BTI_KERNEL
1614+
bool "Use Branch Target Identification for kernel"
1615+
default y
1616+
depends on ARM64_BTI
1617+
depends on ARM64_PTR_AUTH
1618+
depends on CC_HAS_BRANCH_PROT_PAC_RET_BTI
1619+
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94697
1620+
depends on !CC_IS_GCC || GCC_VERSION >= 100100
1621+
depends on !(CC_IS_CLANG && GCOV_KERNEL)
1622+
depends on (!FUNCTION_GRAPH_TRACER || DYNAMIC_FTRACE_WITH_REGS)
1623+
help
1624+
Build the kernel with Branch Target Identification annotations
1625+
and enable enforcement of this for kernel code. When this option
1626+
is enabled and the system supports BTI all kernel code including
1627+
modular code must have BTI enabled.
1628+
1629+
config CC_HAS_BRANCH_PROT_PAC_RET_BTI
1630+
# GCC 9 or later, clang 8 or later
1631+
def_bool $(cc-option,-mbranch-protection=pac-ret+leaf+bti)
1632+
15871633
config ARM64_E0PD
15881634
bool "Enable support for E0PD"
15891635
default y

arch/arm64/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,14 @@ branch-prot-flags-y += $(call cc-option,-mbranch-protection=none)
7070

7171
ifeq ($(CONFIG_ARM64_PTR_AUTH),y)
7272
branch-prot-flags-$(CONFIG_CC_HAS_SIGN_RETURN_ADDRESS) := -msign-return-address=all
73+
# We enable additional protection for leaf functions as there is some
74+
# narrow potential for ROP protection benefits and no substantial
75+
# performance impact has been observed.
76+
ifeq ($(CONFIG_ARM64_BTI_KERNEL),y)
77+
branch-prot-flags-$(CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI) := -mbranch-protection=pac-ret+leaf+bti
78+
else
7379
branch-prot-flags-$(CONFIG_CC_HAS_BRANCH_PROT_PAC_RET) := -mbranch-protection=pac-ret+leaf
80+
endif
7481
# -march=armv8.3-a enables the non-nops instructions for PAC, to avoid the
7582
# compiler to generate them and consequently to break the single image contract
7683
# we pass it only to the assembler. This option is utilized only in case of non

arch/arm64/include/asm/assembler.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,4 +736,54 @@ USER(\label, ic ivau, \tmp2) // invalidate I line PoU
736736
.Lyield_out_\@ :
737737
.endm
738738

739+
/*
740+
* This macro emits a program property note section identifying
741+
* architecture features which require special handling, mainly for
742+
* use in assembly files included in the VDSO.
743+
*/
744+
745+
#define NT_GNU_PROPERTY_TYPE_0 5
746+
#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
747+
748+
#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0)
749+
#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1)
750+
751+
#ifdef CONFIG_ARM64_BTI_KERNEL
752+
#define GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT \
753+
((GNU_PROPERTY_AARCH64_FEATURE_1_BTI | \
754+
GNU_PROPERTY_AARCH64_FEATURE_1_PAC))
755+
#endif
756+
757+
#ifdef GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT
758+
.macro emit_aarch64_feature_1_and, feat=GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT
759+
.pushsection .note.gnu.property, "a"
760+
.align 3
761+
.long 2f - 1f
762+
.long 6f - 3f
763+
.long NT_GNU_PROPERTY_TYPE_0
764+
1: .string "GNU"
765+
2:
766+
.align 3
767+
3: .long GNU_PROPERTY_AARCH64_FEATURE_1_AND
768+
.long 5f - 4f
769+
4:
770+
/*
771+
* This is described with an array of char in the Linux API
772+
* spec but the text and all other usage (including binutils,
773+
* clang and GCC) treat this as a 32 bit value so no swizzling
774+
* is required for big endian.
775+
*/
776+
.long \feat
777+
5:
778+
.align 3
779+
6:
780+
.popsection
781+
.endm
782+
783+
#else
784+
.macro emit_aarch64_feature_1_and, feat=0
785+
.endm
786+
787+
#endif /* GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT */
788+
739789
#endif /* __ASM_ASSEMBLER_H */

arch/arm64/include/asm/cpucaps.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@
6262
#define ARM64_HAS_ADDRESS_AUTH 52
6363
#define ARM64_HAS_GENERIC_AUTH 53
6464
#define ARM64_HAS_32BIT_EL1 54
65+
#define ARM64_BTI 55
6566

66-
#define ARM64_NCAPS 55
67+
#define ARM64_NCAPS 56
6768

6869
#endif /* __ASM_CPUCAPS_H */

arch/arm64/include/asm/cpufeature.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,11 @@ static inline bool system_has_prio_mask_debugging(void)
687687
system_uses_irq_prio_masking();
688688
}
689689

690+
static inline bool system_supports_bti(void)
691+
{
692+
return IS_ENABLED(CONFIG_ARM64_BTI) && cpus_have_const_cap(ARM64_BTI);
693+
}
694+
690695
#define ARM64_BP_HARDEN_UNKNOWN -1
691696
#define ARM64_BP_HARDEN_WA_NEEDED 0
692697
#define ARM64_BP_HARDEN_NOT_REQUIRED 1

arch/arm64/include/asm/elf.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,11 @@
114114

115115
#ifndef __ASSEMBLY__
116116

117+
#include <uapi/linux/elf.h>
117118
#include <linux/bug.h>
119+
#include <linux/errno.h>
120+
#include <linux/fs.h>
121+
#include <linux/types.h>
118122
#include <asm/processor.h> /* for signal_minsigstksz, used by ARCH_DLINFO */
119123

120124
typedef unsigned long elf_greg_t;
@@ -224,6 +228,52 @@ extern int aarch32_setup_additional_pages(struct linux_binprm *bprm,
224228

225229
#endif /* CONFIG_COMPAT */
226230

231+
struct arch_elf_state {
232+
int flags;
233+
};
234+
235+
#define ARM64_ELF_BTI (1 << 0)
236+
237+
#define INIT_ARCH_ELF_STATE { \
238+
.flags = 0, \
239+
}
240+
241+
static inline int arch_parse_elf_property(u32 type, const void *data,
242+
size_t datasz, bool compat,
243+
struct arch_elf_state *arch)
244+
{
245+
/* No known properties for AArch32 yet */
246+
if (IS_ENABLED(CONFIG_COMPAT) && compat)
247+
return 0;
248+
249+
if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) {
250+
const u32 *p = data;
251+
252+
if (datasz != sizeof(*p))
253+
return -ENOEXEC;
254+
255+
if (system_supports_bti() &&
256+
(*p & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
257+
arch->flags |= ARM64_ELF_BTI;
258+
}
259+
260+
return 0;
261+
}
262+
263+
static inline int arch_elf_pt_proc(void *ehdr, void *phdr,
264+
struct file *f, bool is_interp,
265+
struct arch_elf_state *state)
266+
{
267+
return 0;
268+
}
269+
270+
static inline int arch_check_elf(void *ehdr, bool has_interp,
271+
void *interp_ehdr,
272+
struct arch_elf_state *state)
273+
{
274+
return 0;
275+
}
276+
227277
#endif /* !__ASSEMBLY__ */
228278

229279
#endif

arch/arm64/include/asm/esr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#define ESR_ELx_EC_PAC (0x09) /* EL2 and above */
2323
/* Unallocated EC: 0x0A - 0x0B */
2424
#define ESR_ELx_EC_CP14_64 (0x0C)
25-
/* Unallocated EC: 0x0d */
25+
#define ESR_ELx_EC_BTI (0x0D)
2626
#define ESR_ELx_EC_ILL (0x0E)
2727
/* Unallocated EC: 0x0F - 0x10 */
2828
#define ESR_ELx_EC_SVC32 (0x11)

0 commit comments

Comments
 (0)