794 lines · plain
1// RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe2// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck -check-prefix=PACRET %s3// RUN: llvm-bolt-binary-analysis --scanners=pauth --auth-traps-on-failure %t.exe 2>&1 | FileCheck -check-prefix=FPAC %s4// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s5 6// The detection of compiler-generated explicit pointer checks is tested in7// gs-pauth-address-checks.s, for that reason only test here "dummy-load" and8// "high-bits-notbi" checkers, as the shortest examples of checkers that are9// detected per-instruction and per-BB.10 11// PACRET-NOT: authentication oracle found in function12// FPAC-NOT: authentication oracle found in function13 14 .text15 16 .type sym,@function17sym:18 ret19 .size sym, .-sym20 21 .globl callee22 .type callee,@function23callee:24 ret25 .size callee, .-callee26 27 .globl good_ret28 .type good_ret,@function29good_ret:30// CHECK-NOT: good_ret31 autia x0, x132 ret x033 .size good_ret, .-good_ret34 35 .globl good_call36 .type good_call,@function37good_call:38// CHECK-NOT: good_call39 paciasp40 stp x29, x30, [sp, #-16]!41 mov x29, sp42 43 autia x0, x144 blr x045 46 ldp x29, x30, [sp], #1647 autiasp48 ret49 .size good_call, .-good_call50 51 .globl good_branch52 .type good_branch,@function53good_branch:54// CHECK-NOT: good_branch55 autia x0, x156 br x057 .size good_branch, .-good_branch58 59 .globl good_load_other_reg60 .type good_load_other_reg,@function61good_load_other_reg:62// CHECK-NOT: good_load_other_reg63 autia x0, x164 ldr x2, [x0]65 ret66 .size good_load_other_reg, .-good_load_other_reg67 68 .globl good_load_same_reg69 .type good_load_same_reg,@function70good_load_same_reg:71// CHECK-NOT: good_load_same_reg72 autia x0, x173 ldr x0, [x0]74 ret75 .size good_load_same_reg, .-good_load_same_reg76 77 .globl good_explicit_check78 .type good_explicit_check,@function79good_explicit_check:80// CHECK-NOT: good_explicit_check81 autia x0, x182 eor x16, x0, x0, lsl #183 tbz x16, #62, 1f84 brk 0xc470851:86 ret87 .size good_explicit_check, .-good_explicit_check88 89 .globl bad_unchecked90 .type bad_unchecked,@function91bad_unchecked:92// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unchecked, basic block {{[^,]+}}, at address93// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x194// CHECK-NEXT: The 0 instructions that leak the affected registers are:95 autia x0, x196 ret97 .size bad_unchecked, .-bad_unchecked98 99 .globl bad_leaked_to_subroutine100 .type bad_leaked_to_subroutine,@function101bad_leaked_to_subroutine:102// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_leaked_to_subroutine, basic block {{[^,]+}}, at address103// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1104// CHECK-NEXT: The 1 instructions that leak the affected registers are:105// CHECK-NEXT: 1. {{[0-9a-f]+}}: bl callee106// CHECK-NEXT: This happens in the following basic block:107// CHECK-NEXT: {{[0-9a-f]+}}: paciasp108// CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]!109// CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp110// CHECK-NEXT: {{[0-9a-f]+}}: autia x0, x1111// CHECK-NEXT: {{[0-9a-f]+}}: bl callee112// CHECK-NEXT: {{[0-9a-f]+}}: ldr x2, [x0]113// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10114// CHECK-NEXT: {{[0-9a-f]+}}: autiasp115// CHECK-NEXT: {{[0-9a-f]+}}: ret116 paciasp117 stp x29, x30, [sp, #-16]!118 mov x29, sp119 120 autia x0, x1121 bl callee122 ldr x2, [x0]123 124 ldp x29, x30, [sp], #16125 autiasp126 ret127 .size bad_leaked_to_subroutine, .-bad_leaked_to_subroutine128 129 .globl bad_unknown_usage_read130 .type bad_unknown_usage_read,@function131bad_unknown_usage_read:132// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_read, basic block {{[^,]+}}, at address133// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1134// CHECK-NEXT: The 1 instructions that leak the affected registers are:135// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul x3, x0, x1136// CHECK-NEXT: This happens in the following basic block:137// CHECK-NEXT: {{[0-9a-f]+}}: autia x0, x1138// CHECK-NEXT: {{[0-9a-f]+}}: mul x3, x0, x1139// CHECK-NEXT: {{[0-9a-f]+}}: ldr x2, [x0]140// CHECK-NEXT: {{[0-9a-f]+}}: ret141 autia x0, x1142 // Registers are not accessible to an attacker under Pointer143 // Authentication threat model, until spilled to memory.144 // Thus, reporting the below MUL instruction is a false positive, since145 // the next LDR instruction prevents any possible spilling of x3 unless146 // the authentication succeeded. Though, rejecting anything except for147 // a closed list of instruction types is the intended behavior of the148 // analysis, so this false positive is by design.149 mul x3, x0, x1150 ldr x2, [x0]151 ret152 .size bad_unknown_usage_read, .-bad_unknown_usage_read153 154 .globl bad_store_to_memory_and_wait155 .type bad_store_to_memory_and_wait,@function156bad_store_to_memory_and_wait:157// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_store_to_memory_and_wait, basic block {{[^,]+}}, at address158// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1159// CHECK-NEXT: The 1 instructions that leak the affected registers are:160// CHECK-NEXT: 1. {{[0-9a-f]+}}: str x0, [x3]161 autia x0, x1162 cbz x3, 2f163 str x0, [x3]1641:165 // The thread performs a time-consuming computation while the result of166 // authentication is accessible in memory.167 nop1682:169 ldr x2, [x0]170 ret171 .size bad_store_to_memory_and_wait, .-bad_store_to_memory_and_wait172 173// FIXME: Known false negative: if no return instruction is reachable from a174// program point (this probably implies an infinite loop), such175// instruction cannot be detected as an authentication oracle.176 .globl bad_store_to_memory_and_hang177 .type bad_store_to_memory_and_hang,@function178bad_store_to_memory_and_hang:179// CHECK-NOT: bad_store_to_memory_and_hang180 autia x0, x1181 cbz x3, 2f182 str x0, [x3]1831:184 // The thread loops indefinitely while the result of authentication185 // is accessible in memory.186 b 1b1872:188 ldr x2, [x0]189 ret190 .size bad_store_to_memory_and_hang, .-bad_store_to_memory_and_hang191 192 .globl bad_unknown_usage_subreg_read193 .type bad_unknown_usage_subreg_read,@function194bad_unknown_usage_subreg_read:195// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_subreg_read, basic block {{[^,]+}}, at address196// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1197// CHECK-NEXT: The 1 instructions that leak the affected registers are:198// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul w3, w0, w1199// CHECK-NEXT: This happens in the following basic block:200// CHECK-NEXT: {{[0-9a-f]+}}: autia x0, x1201// CHECK-NEXT: {{[0-9a-f]+}}: mul w3, w0, w1202// CHECK-NEXT: {{[0-9a-f]+}}: ldr x2, [x0]203// CHECK-NEXT: {{[0-9a-f]+}}: ret204 autia x0, x1205 mul w3, w0, w1206 ldr x2, [x0]207 ret208 .size bad_unknown_usage_subreg_read, .-bad_unknown_usage_subreg_read209 210 .globl bad_unknown_usage_update211 .type bad_unknown_usage_update,@function212bad_unknown_usage_update:213// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_update, basic block {{[^,]+}}, at address214// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1215// CHECK-NEXT: The 1 instructions that leak the affected registers are:216// CHECK-NEXT: 1. {{[0-9a-f]+}}: movk x0, #0x2a, lsl #16217// CHECK-NEXT: This happens in the following basic block:218// CHECK-NEXT: {{[0-9a-f]+}}: autia x0, x1219// CHECK-NEXT: {{[0-9a-f]+}}: movk x0, #0x2a, lsl #16220// CHECK-NEXT: {{[0-9a-f]+}}: ldr x2, [x0]221// CHECK-NEXT: {{[0-9a-f]+}}: ret222 autia x0, x1223 movk x0, #42, lsl #16 // does not overwrite x0 completely224 ldr x2, [x0]225 ret226 .size bad_unknown_usage_update, .-bad_unknown_usage_update227 228 .globl good_overwrite_with_constant229 .type good_overwrite_with_constant,@function230good_overwrite_with_constant:231// CHECK-NOT: good_overwrite_with_constant232 autia x0, x1233 mov x0, #42234 ret235 .size good_overwrite_with_constant, .-good_overwrite_with_constant236 237// Overwriting sensitive data by instructions with unmodelled side-effects is238// explicitly rejected, even though this particular MRS is safe.239 .globl bad_overwrite_with_side_effects240 .type bad_overwrite_with_side_effects,@function241bad_overwrite_with_side_effects:242// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_overwrite_with_side_effects, basic block {{[^,]+}}, at address243// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1244// CHECK-NEXT: The 0 instructions that leak the affected registers are:245 autia x0, x1246 mrs x0, CTR_EL0247 ret248 .size bad_overwrite_with_side_effects, .-bad_overwrite_with_side_effects249 250// Here the new value written by MUL to x0 is completely unrelated to the result251// of authentication, so this is a false positive.252// FIXME: Can/should we generalize overwriting by constant to handle such cases?253 .globl good_unknown_overwrite254 .type good_unknown_overwrite,@function255good_unknown_overwrite:256// CHECK-LABEL: GS-PAUTH: authentication oracle found in function good_unknown_overwrite, basic block {{[^,]+}}, at address257// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1258// CHECK-NEXT: The 0 instructions that leak the affected registers are:259 autia x0, x1260 mul x0, x1, x2261 ret262 .size good_unknown_overwrite, .-good_unknown_overwrite263 264// This is a false positive: when a general-purpose register is written to as265// a 32-bit register, its top 32 bits are zeroed, but according to LLVM266// representation, the instruction only overwrites the Wn register.267 .globl good_wreg_overwrite268 .type good_wreg_overwrite,@function269good_wreg_overwrite:270// CHECK-LABEL: GS-PAUTH: authentication oracle found in function good_wreg_overwrite, basic block {{[^,]+}}, at address271// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1272 autia x0, x1273 mov w0, #42274 ret275 .size good_wreg_overwrite, .-good_wreg_overwrite276 277 .globl good_address_arith278 .type good_address_arith,@function279good_address_arith:280// CHECK-NOT: good_address_arith281 autia x0, x1282 283 add x1, x0, #8284 sub x2, x1, #16285 mov x3, x2286 287 ldr x4, [x3]288 mov x0, #0289 mov x1, #0290 mov x2, #0291 292 ret293 .size good_address_arith, .-good_address_arith294 295 .globl good_ret_multi_bb296 .type good_ret_multi_bb,@function297good_ret_multi_bb:298// CHECK-NOT: good_ret_multi_bb299 autia x0, x1300 cbz x1, 1f301 nop3021:303 ret x0304 .size good_ret_multi_bb, .-good_ret_multi_bb305 306 .globl good_call_multi_bb307 .type good_call_multi_bb,@function308good_call_multi_bb:309// CHECK-NOT: good_call_multi_bb310 paciasp311 stp x29, x30, [sp, #-16]!312 mov x29, sp313 314 autia x0, x1315 cbz x1, 1f316 nop3171:318 blr x0319 cbz x1, 2f320 nop3212:322 ldp x29, x30, [sp], #16323 autiasp324 ret325 .size good_call_multi_bb, .-good_call_multi_bb326 327 .globl good_branch_multi_bb328 .type good_branch_multi_bb,@function329good_branch_multi_bb:330// CHECK-NOT: good_branch_multi_bb331 autia x0, x1332 cbz x1, 1f333 nop3341:335 br x0336 .size good_branch_multi_bb, .-good_branch_multi_bb337 338 .globl good_load_other_reg_multi_bb339 .type good_load_other_reg_multi_bb,@function340good_load_other_reg_multi_bb:341// CHECK-NOT: good_load_other_reg_multi_bb342 autia x0, x1343 cbz x1, 1f344 nop3451:346 ldr x2, [x0]347 cbz x1, 2f348 nop3492:350 ret351 .size good_load_other_reg_multi_bb, .-good_load_other_reg_multi_bb352 353 .globl good_load_same_reg_multi_bb354 .type good_load_same_reg_multi_bb,@function355good_load_same_reg_multi_bb:356// CHECK-NOT: good_load_same_reg_multi_bb357 autia x0, x1358 cbz x1, 1f359 nop3601:361 ldr x0, [x0]362 cbz x1, 2f363 nop3642:365 ret366 .size good_load_same_reg_multi_bb, .-good_load_same_reg_multi_bb367 368 .globl good_explicit_check_multi_bb369 .type good_explicit_check_multi_bb,@function370good_explicit_check_multi_bb:371// CHECK-NOT: good_explicit_check_multi_bb372 autia x0, x1373 cbz x1, 1f374 nop3751:376 eor x16, x0, x0, lsl #1377 tbz x16, #62, 2f378 brk 0xc4703792:380 cbz x1, 3f381 nop3823:383 ret384 .size good_explicit_check_multi_bb, .-good_explicit_check_multi_bb385 386 .globl bad_unchecked_multi_bb387 .type bad_unchecked_multi_bb,@function388bad_unchecked_multi_bb:389// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unchecked_multi_bb, basic block {{[^,]+}}, at address390// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1391// CHECK-NEXT: The 0 instructions that leak the affected registers are:392 autia x0, x1393 cbz x1, 1f394 ldr x2, [x0]3951:396 ret397 .size bad_unchecked_multi_bb, .-bad_unchecked_multi_bb398 399 .globl bad_leaked_to_subroutine_multi_bb400 .type bad_leaked_to_subroutine_multi_bb,@function401bad_leaked_to_subroutine_multi_bb:402// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_leaked_to_subroutine_multi_bb, basic block {{[^,]+}}, at address403// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1404// CHECK-NEXT: The 1 instructions that leak the affected registers are:405// CHECK-NEXT: 1. {{[0-9a-f]+}}: bl callee406 paciasp407 stp x29, x30, [sp, #-16]!408 mov x29, sp409 410 autia x0, x1411 cbz x1, 1f412 ldr x2, [x0]4131:414 bl callee415 ldr x2, [x0]416 417 ldp x29, x30, [sp], #16418 autiasp419 ret420 .size bad_leaked_to_subroutine_multi_bb, .-bad_leaked_to_subroutine_multi_bb421 422 .globl bad_unknown_usage_read_multi_bb423 .type bad_unknown_usage_read_multi_bb,@function424bad_unknown_usage_read_multi_bb:425// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_read_multi_bb, basic block {{[^,]+}}, at address426// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1427// CHECK-NEXT: The 1 instructions that leak the affected registers are:428// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul x3, x0, x1429 autia x0, x1430 cbz x3, 1f431 mul x3, x0, x14321:433 ldr x2, [x0]434 ret435 .size bad_unknown_usage_read_multi_bb, .-bad_unknown_usage_read_multi_bb436 437 .globl bad_unknown_usage_subreg_read_multi_bb438 .type bad_unknown_usage_subreg_read_multi_bb,@function439bad_unknown_usage_subreg_read_multi_bb:440// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_subreg_read_multi_bb, basic block {{[^,]+}}, at address441// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1442// CHECK-NEXT: The 1 instructions that leak the affected registers are:443// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul w3, w0, w1444 autia x0, x1445 cbz x3, 1f446 mul w3, w0, w14471:448 ldr x2, [x0]449 ret450 .size bad_unknown_usage_subreg_read_multi_bb, .-bad_unknown_usage_subreg_read_multi_bb451 452 .globl bad_unknown_usage_update_multi_bb453 .type bad_unknown_usage_update_multi_bb,@function454bad_unknown_usage_update_multi_bb:455// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_update_multi_bb, basic block {{[^,]+}}, at address456// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1457// CHECK-NEXT: The 1 instructions that leak the affected registers are:458// CHECK-NEXT: 1. {{[0-9a-f]+}}: movk x0, #0x2a, lsl #16459 autia x0, x1460 cbz x3, 1f461 movk x0, #42, lsl #16 // does not overwrite x0 completely4621:463 ldr x2, [x0]464 ret465 .size bad_unknown_usage_update_multi_bb, .-bad_unknown_usage_update_multi_bb466 467 .globl good_overwrite_with_constant_multi_bb468 .type good_overwrite_with_constant_multi_bb,@function469good_overwrite_with_constant_multi_bb:470// CHECK-NOT: good_overwrite_with_constant_multi_bb471 autia x0, x1472 cbz x3, 1f4731:474 mov x0, #42475 ret476 .size good_overwrite_with_constant_multi_bb, .-good_overwrite_with_constant_multi_bb477 478 .globl good_address_arith_multi_bb479 .type good_address_arith_multi_bb,@function480good_address_arith_multi_bb:481// CHECK-NOT: good_address_arith_multi_bb482 autia x0, x1483 cbz x3, 1f484 485 add x1, x0, #8486 sub x2, x1, #16487 mov x0, x2488 489 mov x1, #0490 mov x2, #04911:492 ldr x3, [x0]493 ret494 .size good_address_arith_multi_bb, .-good_address_arith_multi_bb495 496 .globl good_ret_nocfg497 .type good_ret_nocfg,@function498good_ret_nocfg:499// CHECK-NOT: good_ret_nocfg500 adr x2, 1f501 br x25021:503 autia x0, x1504 505 ret x0506 .size good_ret_nocfg, .-good_ret_nocfg507 508 .globl good_call_nocfg509 .type good_call_nocfg,@function510good_call_nocfg:511// CHECK-NOT: good_call_nocfg512 paciasp513 stp x29, x30, [sp, #-16]!514 mov x29, sp515 516 adr x2, 1f517 br x25181:519 autia x0, x1520 blr x0521 522 ldp x29, x30, [sp], #16523 autiasp524 ret525 .size good_call_nocfg, .-good_call_nocfg526 527 .globl good_branch_nocfg528 .type good_branch_nocfg,@function529good_branch_nocfg:530// CHECK-NOT: good_branch_nocfg531 adr x2, 1f532 br x25331:534 autia x0, x1535 br x0536 .size good_branch_nocfg, .-good_branch_nocfg537 538 .globl good_load_other_reg_nocfg539 .type good_load_other_reg_nocfg,@function540good_load_other_reg_nocfg:541// CHECK-NOT: good_load_other_reg_nocfg542 adr x2, 1f543 br x25441:545 autia x0, x1546 ldr x2, [x0]547 548 ret549 .size good_load_other_reg_nocfg, .-good_load_other_reg_nocfg550 551 .globl good_load_same_reg_nocfg552 .type good_load_same_reg_nocfg,@function553good_load_same_reg_nocfg:554// CHECK-NOT: good_load_same_reg_nocfg555 adr x2, 1f556 br x25571:558 autia x0, x1559 ldr x0, [x0]560 561 ret562 .size good_load_same_reg_nocfg, .-good_load_same_reg_nocfg563 564// FIXME: Multi-instruction checker sequences are not supported without CFG.565 566 .globl bad_unchecked_nocfg567 .type bad_unchecked_nocfg,@function568bad_unchecked_nocfg:569// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unchecked_nocfg, at address570// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1571// CHECK-NEXT: The 0 instructions that leak the affected registers are:572 adr x2, 1f573 br x25741:575 autia x0, x1576 577 ret578 .size bad_unchecked_nocfg, .-bad_unchecked_nocfg579 580 .globl bad_leaked_to_subroutine_nocfg581 .type bad_leaked_to_subroutine_nocfg,@function582bad_leaked_to_subroutine_nocfg:583// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_leaked_to_subroutine_nocfg, at address584// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1585// CHECK-NEXT: The 1 instructions that leak the affected registers are:586// CHECK-NEXT: 1. {{[0-9a-f]+}}: bl callee # Offset: 24587 paciasp588 stp x29, x30, [sp, #-16]!589 mov x29, sp590 591 adr x2, 1f592 br x25931:594 autia x0, x1595 bl callee596 ldr x2, [x0]597 598 ldp x29, x30, [sp], #16599 autiasp600 ret601 .size bad_leaked_to_subroutine_nocfg, .-bad_leaked_to_subroutine_nocfg602 603 .globl bad_unknown_usage_read_nocfg604 .type bad_unknown_usage_read_nocfg,@function605bad_unknown_usage_read_nocfg:606// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_read_nocfg, at address607// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1608// CHECK-NEXT: The 1 instructions that leak the affected registers are:609// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul x3, x0, x1610 adr x2, 1f611 br x26121:613 autia x0, x1614 mul x3, x0, x1615 ldr x2, [x0]616 617 ret618 .size bad_unknown_usage_read_nocfg, .-bad_unknown_usage_read_nocfg619 620 .globl bad_unknown_usage_subreg_read_nocfg621 .type bad_unknown_usage_subreg_read_nocfg,@function622bad_unknown_usage_subreg_read_nocfg:623// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_subreg_read_nocfg, at address624// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1625// CHECK-NEXT: The 1 instructions that leak the affected registers are:626// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul w3, w0, w1627 adr x2, 1f628 br x26291:630 autia x0, x1631 mul w3, w0, w1632 ldr x2, [x0]633 634 ret635 .size bad_unknown_usage_subreg_read_nocfg, .-bad_unknown_usage_subreg_read_nocfg636 637 .globl bad_unknown_usage_update_nocfg638 .type bad_unknown_usage_update_nocfg,@function639bad_unknown_usage_update_nocfg:640// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_update_nocfg, at address641// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1642// CHECK-NEXT: The 1 instructions that leak the affected registers are:643// CHECK-NEXT: 1. {{[0-9a-f]+}}: movk x0, #0x2a, lsl #16644 adr x2, 1f645 br x26461:647 autia x0, x1648 movk x0, #42, lsl #16 // does not overwrite x0 completely649 ldr x2, [x0]650 651 ret652 .size bad_unknown_usage_update_nocfg, .-bad_unknown_usage_update_nocfg653 654 .globl good_overwrite_with_constant_nocfg655 .type good_overwrite_with_constant_nocfg,@function656good_overwrite_with_constant_nocfg:657// CHECK-NOT: good_overwrite_with_constant_nocfg658 adr x2, 1f659 br x26601:661 autia x0, x1662 mov x0, #42663 664 ret665 .size good_overwrite_with_constant_nocfg, .-good_overwrite_with_constant_nocfg666 667 .globl good_address_arith_nocfg668 .type good_address_arith_nocfg,@function669good_address_arith_nocfg:670// CHECK-NOT: good_address_arith_nocfg671 adr x2, 1f672 br x26731:674 autia x0, x1675 add x1, x0, #8676 sub x2, x1, #16677 mov x3, x2678 679 ldr x4, [x3]680 mov x0, #0681 mov x1, #0682 mov x2, #0683 684 ret685 .size good_address_arith_nocfg, .-good_address_arith_nocfg686 687 .globl good_explicit_check_unrelated_reg688 .type good_explicit_check_unrelated_reg,@function689good_explicit_check_unrelated_reg:690// CHECK-NOT: good_explicit_check_unrelated_reg691 autia x2, x3 // One of possible execution paths after this instruction692 // ends at BRK below, thus BRK used as a trap instruction693 // should formally "check everything" not to introduce694 // false-positive here.695 autia x0, x1696 eor x16, x0, x0, lsl #1697 tbz x16, #62, 1f698 brk 0xc4706991:700 ldr x4, [x2] // Right before this instruction X2 is checked - this701 // should be propagated to the basic block ending with702 // TBZ instruction above.703 ret704 .size good_explicit_check_unrelated_reg, .-good_explicit_check_unrelated_reg705 706// The last BB (in layout order) is processed first by the data-flow analysis.707// Its initial state is usually filled in a special way (because it ends with708// `ret` instruction), and then affects the state propagated to the other BBs709// Thus, the case of the last instruction in a function being a jump somewhere710// in the middle is special.711 712 .globl good_no_ret_from_last_bb713 .type good_no_ret_from_last_bb,@function714good_no_ret_from_last_bb:715// CHECK-NOT: good_no_ret_from_last_bb716 paciasp717 autiasp // authenticates LR718 b 2f7191:720 ret7212:722 b 1b // LR is dereferenced by `ret`, which is executed next723 .size good_no_ret_from_last_bb, .-good_no_ret_from_last_bb724 725 .globl bad_no_ret_from_last_bb726 .type bad_no_ret_from_last_bb,@function727bad_no_ret_from_last_bb:728// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_no_ret_from_last_bb, basic block {{[^,]+}}, at address729// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp730// CHECK-NEXT: The 0 instructions that leak the affected registers are:731 paciasp732 autiasp // authenticates LR733 b 2f7341:735 ret x07362:737 b 1b // X0 (but not LR) is dereferenced by `ret x0`738 .size bad_no_ret_from_last_bb, .-bad_no_ret_from_last_bb739 740// Test that combined auth+something instructions are not reported as741// authentication oracles.742 743 .globl inst_retaa744 .type inst_retaa,@function745inst_retaa:746// CHECK-NOT: inst_retaa747 paciasp748 retaa749 .size inst_retaa, .-inst_retaa750 751 .globl inst_blraa752 .type inst_blraa,@function753inst_blraa:754// CHECK-NOT: inst_blraa755 paciasp756 stp x29, x30, [sp, #-16]!757 mov x29, sp758 759 blraa x0, x1760 761 ldp x29, x30, [sp], #16762 retaa763 .size inst_blraa, .-inst_blraa764 765 .globl inst_braa766 .type inst_braa,@function767inst_braa:768// CHECK-NOT: inst_braa769 braa x0, x1770 .size inst_braa, .-inst_braa771 772 .globl inst_ldraa_no_wb773 .type inst_ldraa_no_wb,@function774inst_ldraa_no_wb:775// CHECK-NOT: inst_ldraa_no_wb776 ldraa x1, [x0]777 ret778 .size inst_ldraa_no_wb, .-inst_ldraa_no_wb779 780 .globl inst_ldraa_wb781 .type inst_ldraa_wb,@function782inst_ldraa_wb:783// CHECK-NOT: inst_ldraa_wb784 ldraa x1, [x0]!785 ret786 .size inst_ldraa_wb, .-inst_ldraa_wb787 788 .globl main789 .type main,@function790main:791 mov x0, 0792 ret793 .size main, .-main794