261 lines · plain
1// -Wl,--no-relax prevents converting ADRP+ADD pairs into NOP+ADR.2// RUN: %clang %cflags -march=armv8.3-a -Wl,--no-relax %s -o %t.exe3// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s4 5// Test various patterns that should or should not be considered safe6// materialization of PC-relative addresses.7//8// Note that while "instructions that write to the affected registers"9// section of the report is still technically correct, it does not necessarily10// mention the instructions that are used incorrectly.11 12 .text13 14// Define a function that is reachable by ADR instruction.15 .type sym,@function16sym:17 ret18 .size sym, .-sym19 20 .globl good_adr21 .type good_adr,@function22good_adr:23// CHECK-NOT: good_adr24 adr x0, sym25 paciza x026 ret27 .size good_adr, .-good_adr28 29 .globl good_adrp30 .type good_adrp,@function31good_adrp:32// CHECK-NOT: good_adrp33 adrp x0, sym34 paciza x035 ret36 .size good_adrp, .-good_adrp37 38 .globl good_adrp_add39 .type good_adrp_add,@function40good_adrp_add:41// CHECK-NOT: good_adrp_add42 adrp x0, sym43 add x0, x0, :lo12:sym44 paciza x045 ret46 .size good_adrp_add, .-good_adrp_add47 48 .globl good_adrp_add_with_const_offset49 .type good_adrp_add_with_const_offset,@function50good_adrp_add_with_const_offset:51// CHECK-NOT: good_adrp_add_with_const_offset52 adrp x0, sym53 add x0, x0, :lo12:sym54 add x0, x0, #855 paciza x056 ret57 .size good_adrp_add_with_const_offset, .-good_adrp_add_with_const_offset58 59 .globl bad_adrp_with_nonconst_offset60 .type bad_adrp_with_nonconst_offset,@function61bad_adrp_with_nonconst_offset:62// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_adrp_with_nonconst_offset, basic block {{[^,]+}}, at address63// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x064// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:65// CHECK-NEXT: 1. {{[0-9a-f]+}}: add x0, x0, x166// CHECK-NEXT: This happens in the following basic block:67// CHECK-NEXT: {{[0-9a-f]+}}: adrp x0, #{{.*}}68// CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, x169// CHECK-NEXT: {{[0-9a-f]+}}: paciza x070// CHECK-NEXT: {{[0-9a-f]+}}: ret71 adrp x0, sym72 add x0, x0, x173 paciza x074 ret75 .size bad_adrp_with_nonconst_offset, .-bad_adrp_with_nonconst_offset76 77 .globl bad_split_adrp78 .type bad_split_adrp,@function79bad_split_adrp:80// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_split_adrp, basic block {{[^,]+}}, at address81// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x082// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:83// CHECK-NEXT: 1. {{[0-9a-f]+}}: add x0, x0, #0x{{[0-9a-f]+}}84// CHECK-NEXT: This happens in the following basic block:85// CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x{{[0-9a-f]+}}86// CHECK-NEXT: {{[0-9a-f]+}}: paciza x087// CHECK-NEXT: {{[0-9a-f]+}}: ret88 cbz x2, 1f89 adrp x0, sym901:91 add x0, x0, :lo12:sym92 paciza x093 ret94 .size bad_split_adrp, .-bad_split_adrp95 96// Materialization of absolute addresses is not handled, as it is not expected97// to be used by real-world code, but can be supported if needed.98 99 .globl bad_immediate_constant100 .type bad_immediate_constant,@function101bad_immediate_constant:102// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_immediate_constant, basic block {{[^,]+}}, at address103// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x0104// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:105// CHECK-NEXT: 1. {{[0-9a-f]+}}: mov x0, #{{.*}}106// CHECK-NEXT: This happens in the following basic block:107// CHECK-NEXT: {{[0-9a-f]+}}: mov x0, #{{.*}}108// CHECK-NEXT: {{[0-9a-f]+}}: paciza x0109// CHECK-NEXT: {{[0-9a-f]+}}: ret110 movz x0, #1234111 paciza x0112 ret113 .size bad_immediate_constant, .-bad_immediate_constant114 115// Any ADR or ADRP instruction followed by any number of increments/decrements116// by constant is considered safe.117 118 .globl good_adr_with_add119 .type good_adr_with_add,@function120good_adr_with_add:121// CHECK-NOT: good_adr_with_add122 adr x0, sym123 add x0, x0, :lo12:sym124 paciza x0125 ret126 .size good_adr_with_add, .-good_adr_with_add127 128 .globl good_adrp_with_add_non_consecutive129 .type good_adrp_with_add_non_consecutive,@function130good_adrp_with_add_non_consecutive:131// CHECK-NOT: good_adrp_with_add_non_consecutive132 adrp x0, sym133 mul x1, x2, x3134 add x0, x0, :lo12:sym135 paciza x0136 ret137 .size good_adrp_with_add_non_consecutive, .-good_adrp_with_add_non_consecutive138 139 .globl good_many_offsets140 .type good_many_offsets,@function141good_many_offsets:142// CHECK-NOT: good_many_offsets143 adrp x0, sym144 add x1, x0, #8145 add x2, x1, :lo12:sym146 paciza x2147 ret148 .size good_many_offsets, .-good_many_offsets149 150 .globl good_negative_offset151 .type good_negative_offset,@function152good_negative_offset:153// CHECK-NOT: good_negative_offset154 adr x0, sym155 sub x1, x0, #8156 paciza x1157 ret158 .size good_negative_offset, .-good_negative_offset159 160// MOV Xd, Xm (which is an alias of ORR Xd, XZR, Xm) is handled as part of161// support for address arithmetics, but ORR in general is not.162// This restriction may be relaxed in the future.163 164 .globl good_mov_reg165 .type good_mov_reg,@function166good_mov_reg:167// CHECK-NOT: good_mov_reg168 adrp x0, sym169 mov x1, x0170 orr x2, xzr, x1 // the same as "mov x2, x1"171 paciza x2172 ret173 .size good_mov_reg, .-good_mov_reg174 175 .globl bad_orr_not_xzr176 .type bad_orr_not_xzr,@function177bad_orr_not_xzr:178// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_orr_not_xzr, basic block {{[^,]+}}, at address179// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x2180// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:181// CHECK-NEXT: 1. {{[0-9a-f]+}}: orr x2, x1, x0182// CHECK-NEXT: This happens in the following basic block:183// CHECK-NEXT: {{[0-9a-f]+}}: adrp x0, #{{(0x)?[0-9a-f]+}}184// CHECK-NEXT: {{[0-9a-f]+}}: mov x1, #0185// CHECK-NEXT: {{[0-9a-f]+}}: orr x2, x1, x0186// CHECK-NEXT: {{[0-9a-f]+}}: paciza x2187// CHECK-NEXT: {{[0-9a-f]+}}: ret188 adrp x0, sym189 // The generic case of "orr Xd, Xn, Xm" is not allowed so far,190 // even if Xn is known to be safe191 movz x1, #0192 orr x2, x1, x0193 paciza x2194 ret195 .size bad_orr_not_xzr, .-bad_orr_not_xzr196 197 .globl bad_orr_not_lsl0198 .type bad_orr_not_lsl0,@function199bad_orr_not_lsl0:200// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_orr_not_lsl0, basic block {{[^,]+}}, at address201// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x2202// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:203// CHECK-NEXT: 1. {{[0-9a-f]+}}: orr x2, xzr, x0, lsl #1204// CHECK-NEXT: This happens in the following basic block:205// CHECK-NEXT: {{[0-9a-f]+}}: adrp x0, #{{(0x)?[0-9a-f]+}}206// CHECK-NEXT: {{[0-9a-f]+}}: orr x2, xzr, x0, lsl #1207// CHECK-NEXT: {{[0-9a-f]+}}: paciza x2208// CHECK-NEXT: {{[0-9a-f]+}}: ret209 adrp x0, sym210 // Currently, the only allowed form of "orr" is that used by "mov Xd, Xn" alias.211 // This can be relaxed in the future.212 orr x2, xzr, x0, lsl #1213 paciza x2214 ret215 .size bad_orr_not_lsl0, .-bad_orr_not_lsl0216 217// Check that the input register operands of `add`/`mov` is correct.218 219 .globl bad_add_input_reg220 .type bad_add_input_reg,@function221bad_add_input_reg:222// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_add_input_reg, basic block {{[^,]+}}, at address223// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x0224// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:225// CHECK-NEXT: 1. {{[0-9a-f]+}}: add x0, x1, #0x{{[0-9a-f]+}}226// CHECK-NEXT: This happens in the following basic block:227// CHECK-NEXT: {{[0-9a-f]+}}: adrp x0, #{{(0x)?[0-9a-f]+}}228// CHECK-NEXT: {{[0-9a-f]+}}: add x0, x1, #0x{{[0-9a-f]+}}229// CHECK-NEXT: {{[0-9a-f]+}}: paciza x0230// CHECK-NEXT: {{[0-9a-f]+}}: ret231 adrp x0, sym232 add x0, x1, :lo12:sym233 paciza x0234 ret235 .size bad_add_input_reg, .-bad_add_input_reg236 237 .globl bad_mov_input_reg238 .type bad_mov_input_reg,@function239bad_mov_input_reg:240// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_mov_input_reg, basic block {{[^,]+}}, at address241// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x0242// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:243// CHECK-NEXT: 1. {{[0-9a-f]+}}: mov x0, x1244// CHECK-NEXT: This happens in the following basic block:245// CHECK-NEXT: {{[0-9a-f]+}}: adrp x0, #{{(0x)?[0-9a-f]+}}246// CHECK-NEXT: {{[0-9a-f]+}}: mov x0, x1247// CHECK-NEXT: {{[0-9a-f]+}}: paciza x0248// CHECK-NEXT: {{[0-9a-f]+}}: ret249 adrp x0, sym250 mov x0, x1251 paciza x0252 ret253 .size bad_mov_input_reg, .-bad_mov_input_reg254 255 .globl main256 .type main,@function257main:258 mov x0, 0259 ret260 .size main, .-main261