History

arm64: expose user PAC bit positions via ptrace

When pointer authentication is in use, data/instruction pointers have a number of PAC bits inserted into them. The number and position of these bits depends on the configured TCR_ELx.TxSZ and whether tagging is enabled. ARMv8.3 allows tagging to differ for instruction and data pointers. For userspace debuggers to unwind the stack and/or to follow pointer chains, they need to be able to remove the PAC bits before attempting to use a pointer. This patch adds a new structure with masks describing the location of the PAC bits in userspace instruction and data pointers (i.e. those addressable via TTBR0), which userspace can query via PTRACE_GETREGSET. By clearing these bits from pointers (and replacing them with the value of bit 55), userspace can acquire the PAC-less versions. This new regset is exposed when the kernel is built with (user) pointer authentication support, and the address authentication feature is enabled. Otherwise, the regset is hidden.

Mark Rutland committed 7 years ago

Commit ec6e8221 parent 75031976 files · +57 −2Browse files

Unified · Split

6 files
  1. arch/arm64/include/asm/memory.h +3 −0
  2. arch/arm64/include/asm/pointer_auth.h +8 −0
  3. arch/arm64/include/asm/processor.h +0 −2
  4. arch/arm64/include/uapi/asm/ptrace.h +7 −0
  5. arch/arm64/kernel/ptrace.c +38 −0
  6. include/uapi/linux/elf.h +1 −0
arch/arm64/include/asm/memory.h+3−0
@@ -207,6 +207,9 @@ static inline unsigned long kaslr_offset(void) · 206 unmodified lines
207207 return kimage_vaddr - KIMAGE_VADDR;
208208 }
209209
210+/* the actual size of a user virtual address */
211+extern u64 vabits_user;
212+
210213 /*
211214 * Allow all memory at the discovery stage. We will clip it later.
212215 */
arch/arm64/include/asm/pointer_auth.h+8−0
@@ -2,9 +2,11 @@ · 1 unmodified line
22 #ifndef __ASM_POINTER_AUTH_H
33 #define __ASM_POINTER_AUTH_H
44
5+#include <linux/bitops.h>
56 #include <linux/random.h>
67
78 #include <asm/cpufeature.h>
9+#include <asm/memory.h>
810 #include <asm/sysreg.h>
911
1012 #ifdef CONFIG_ARM64_PTR_AUTH
@@ -61,6 +63,12 @@ static inline void ptrauth_keys_switch(struct ptrauth_keys *keys) · 50 unmodified lines
6163 __ptrauth_key_install(APGA, keys->apga);
6264 }
6365
66+/*
67+ * The EL0 pointer bits used by a pointer authentication code.
68+ * This is dependent on TBI0 being enabled, or bits 63:56 would also apply.
69+ */
70+#define ptrauth_user_pac_mask() GENMASK(54, vabits_user)
71+
6472 #define ptrauth_thread_init_user(tsk) \
6573 do { \
6674 struct task_struct *__ptiu_tsk = (tsk); \
arch/arm64/include/asm/processor.h+0−2
@@ -53,8 +53,6 @@ · 52 unmodified lines
5353 */
5454
5555 #define DEFAULT_MAP_WINDOW_64 (UL(1) << VA_BITS)
56−
57−extern u64 vabits_user;
5856 #define TASK_SIZE_64 (UL(1) << vabits_user)
5957
6058 #ifdef CONFIG_COMPAT
arch/arm64/include/uapi/asm/ptrace.h+7−0
@@ -229,6 +229,13 @@ struct user_sve_header { · 228 unmodified lines
229229 SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags) \
230230 : SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags))
231231
232+/* pointer authentication masks (NT_ARM_PAC_MASK) */
233+
234+struct user_pac_mask {
235+ __u64 data_mask;
236+ __u64 insn_mask;
237+};
238+
232239 #endif /* __ASSEMBLY__ */
233240
234241 #endif /* _UAPI__ASM_PTRACE_H */
arch/arm64/kernel/ptrace.c+38−0
@@ -46,6 +46,7 @@ · 45 unmodified lines
4646 #include <asm/debug-monitors.h>
4747 #include <asm/fpsimd.h>
4848 #include <asm/pgtable.h>
49+#include <asm/pointer_auth.h>
4950 #include <asm/stacktrace.h>
5051 #include <asm/syscall.h>
5152 #include <asm/traps.h>
@@ -956,6 +957,30 @@ out: · 904 unmodified lines
956957
957958 #endif /* CONFIG_ARM64_SVE */
958959
960+#ifdef CONFIG_ARM64_PTR_AUTH
961+static int pac_mask_get(struct task_struct *target,
962+ const struct user_regset *regset,
963+ unsigned int pos, unsigned int count,
964+ void *kbuf, void __user *ubuf)
965+{
966+ /*
967+ * The PAC bits can differ across data and instruction pointers
968+ * depending on TCR_EL1.TBID*, which we may make use of in future, so
969+ * we expose separate masks.
970+ */
971+ unsigned long mask = ptrauth_user_pac_mask();
972+ struct user_pac_mask uregs = {
973+ .data_mask = mask,
974+ .insn_mask = mask,
975+ };
976+
977+ if (!system_supports_address_auth())
978+ return -EINVAL;
979+
980+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &uregs, 0, -1);
981+}
982+#endif /* CONFIG_ARM64_PTR_AUTH */
983+
959984 enum aarch64_regset {
960985 REGSET_GPR,
961986 REGSET_FPR,
@@ -968,6 +993,9 @@ enum aarch64_regset { · 6 unmodified lines
968993 #ifdef CONFIG_ARM64_SVE
969994 REGSET_SVE,
970995 #endif
996+#ifdef CONFIG_ARM64_PTR_AUTH
997+ REGSET_PAC_MASK,
998+#endif
971999 };
9721000
9731001 static const struct user_regset aarch64_regsets[] = {
@@ -1037,6 +1065,16 @@ static const struct user_regset aarch64_regsets[] = { · 63 unmodified lines
10371065 .get_size = sve_get_size,
10381066 },
10391067 #endif
1068+#ifdef CONFIG_ARM64_PTR_AUTH
1069+ [REGSET_PAC_MASK] = {
1070+ .core_note_type = NT_ARM_PAC_MASK,
1071+ .n = sizeof(struct user_pac_mask) / sizeof(u64),
1072+ .size = sizeof(u64),
1073+ .align = sizeof(u64),
1074+ .get = pac_mask_get,
1075+ /* this cannot be set dynamically */
1076+ },
1077+#endif
10401078 };
10411079
10421080 static const struct user_regset_view user_aarch64_view = {
include/uapi/linux/elf.h+1−0
@@ -420,6 +420,7 @@ typedef struct elf64_shdr { · 419 unmodified lines
420420 #define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */
421421 #define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */
422422 #define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension registers */
423+#define NT_ARM_PAC_MASK 0x406 /* ARM pointer authentication code masks */
423424 #define NT_ARC_V2 0x600 /* ARCv2 accumulator/extra registers */
424425 #define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note */
425426 #define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t