// RUN: %clang %cflags -Wl,--entry=_custom_start -march=armv8.3-a %s -o %t.exe // RUN: llvm-bolt-binary-analysis --scanners=ptrauth-all --auth-traps-on-failure %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,FPAC %s // RUN: llvm-bolt-binary-analysis --scanners=ptrauth-all %t.exe 2>&1 | FileCheck -check-prefixes=CHECK,NOFPAC %s .text .globl callee .type callee,@function callee: ret .size callee, .-callee .globl good_direct_tailcall_no_clobber .type good_direct_tailcall_no_clobber,@function good_direct_tailcall_no_clobber: // CHECK-NOT: good_direct_tailcall_no_clobber b callee .size good_direct_tailcall_no_clobber, .-good_direct_tailcall_no_clobber .globl good_plt_tailcall_no_clobber .type good_plt_tailcall_no_clobber,@function good_plt_tailcall_no_clobber: // CHECK-NOT: good_plt_tailcall_no_clobber b callee_ext .size good_plt_tailcall_no_clobber, .-good_plt_tailcall_no_clobber .globl good_indirect_tailcall_no_clobber .type good_indirect_tailcall_no_clobber,@function good_indirect_tailcall_no_clobber: // CHECK-NOT: good_indirect_tailcall_no_clobber autia x0, x1 br x0 .size good_indirect_tailcall_no_clobber, .-good_indirect_tailcall_no_clobber .globl bad_direct_tailcall_not_auted .type bad_direct_tailcall_not_auted,@function bad_direct_tailcall_not_auted: // CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_not_auted, basic block {{[^,]+}}, at address // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 // CHECK-NEXT: This happens in the following basic block: // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 // CHECK-NEXT: {{[0-9a-f]+}}: b callee # TAILCALL stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 b callee .size bad_direct_tailcall_not_auted, .-bad_direct_tailcall_not_auted .globl bad_plt_tailcall_not_auted .type bad_plt_tailcall_not_auted,@function bad_plt_tailcall_not_auted: // FIXME: Calls via PLT are disassembled incorrectly. Nevertheless, they are // still detected as tail calls. // CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_plt_tailcall_not_auted, basic block {{[^,]+}}, at address // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b bad_indirect_tailcall_not_auted # TAILCALL // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 // CHECK-NEXT: This happens in the following basic block: // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 // CHECK-NEXT: {{[0-9a-f]+}}: b bad_indirect_tailcall_not_auted # TAILCALL stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 b callee_ext .size bad_plt_tailcall_not_auted, .-bad_plt_tailcall_not_auted .globl bad_indirect_tailcall_not_auted .type bad_indirect_tailcall_not_auted,@function bad_indirect_tailcall_not_auted: // CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_not_auted, basic block {{[^,]+}}, at address // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: br x0 # TAILCALL // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 // CHECK-NEXT: This happens in the following basic block: // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 // CHECK-NEXT: {{[0-9a-f]+}}: autia x0, x1 // CHECK-NEXT: {{[0-9a-f]+}}: br x0 # TAILCALL stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 autia x0, x1 br x0 .size bad_indirect_tailcall_not_auted, .-bad_indirect_tailcall_not_auted .globl bad_direct_tailcall_untrusted .type bad_direct_tailcall_untrusted,@function bad_direct_tailcall_untrusted: // FPAC-NOT: bad_direct_tailcall_untrusted // NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_untrusted, basic block {{[^,]+}}, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL // NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are: // NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_direct_tailcall_untrusted, basic block {{[^,]+}}, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp // NOFPAC-NEXT: The 1 instructions that leak the affected registers are: // NOFPAC-NEXT: 1. {{[0-9a-f]+}}: b callee # TAILCALL // NOFPAC-NEXT: This happens in the following basic block: // NOFPAC-NEXT: {{[0-9a-f]+}}: paciasp // NOFPAC-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! // NOFPAC-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 // NOFPAC-NEXT: {{[0-9a-f]+}}: autiasp // NOFPAC-NEXT: {{[0-9a-f]+}}: b callee # TAILCALL paciasp stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 autiasp b callee .size bad_direct_tailcall_untrusted, .-bad_direct_tailcall_untrusted .globl bad_plt_tailcall_untrusted .type bad_plt_tailcall_untrusted,@function bad_plt_tailcall_untrusted: // FIXME: Calls via PLT are disassembled incorrectly. Nevertheless, they are // still detected as tail calls. // FPAC-NOT: bad_plt_tailcall_untrusted // NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_plt_tailcall_untrusted, basic block {{[^,]+}}, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted # TAILCALL // NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are: // NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_plt_tailcall_untrusted, basic block {{[^,]+}}, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp // NOFPAC-NEXT: The 1 instructions that leak the affected registers are: // NOFPAC-NEXT: 1. {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted # TAILCALL // NOFPAC-NEXT: This happens in the following basic block: // NOFPAC-NEXT: {{[0-9a-f]+}}: paciasp // NOFPAC-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! // NOFPAC-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 // NOFPAC-NEXT: {{[0-9a-f]+}}: autiasp // NOFPAC-NEXT: {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted # TAILCALL paciasp stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 autiasp b callee_ext .size bad_plt_tailcall_untrusted, .-bad_plt_tailcall_untrusted .globl bad_indirect_tailcall_untrusted .type bad_indirect_tailcall_untrusted,@function bad_indirect_tailcall_untrusted: // FPAC-NOT: bad_indirect_tailcall_untrusted // NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_untrusted, basic block {{[^,]+}}, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: br x0 # TAILCALL // NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are: // NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted, basic block {{[^,]+}}, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp // NOFPAC-NEXT: The 1 instructions that leak the affected registers are: // NOFPAC-NEXT: 1. {{[0-9a-f]+}}: br x0 # TAILCALL // NOFPAC-NEXT: This happens in the following basic block: // NOFPAC-NEXT: {{[0-9a-f]+}}: paciasp // NOFPAC-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! // NOFPAC-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 // NOFPAC-NEXT: {{[0-9a-f]+}}: autiasp // NOFPAC-NEXT: {{[0-9a-f]+}}: autia x0, x1 // NOFPAC-NEXT: {{[0-9a-f]+}}: br x0 # TAILCALL paciasp stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 autiasp autia x0, x1 br x0 .size bad_indirect_tailcall_untrusted, .-bad_indirect_tailcall_untrusted .globl good_direct_tailcall_trusted .type good_direct_tailcall_trusted,@function good_direct_tailcall_trusted: // CHECK-NOT: good_direct_tailcall_trusted paciasp stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 autiasp ldr w2, [x30] b callee .size good_direct_tailcall_trusted, .-good_direct_tailcall_trusted .globl good_plt_tailcall_trusted .type good_plt_tailcall_trusted,@function good_plt_tailcall_trusted: // CHECK-NOT: good_plt_tailcall_trusted paciasp stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 autiasp ldr w2, [x30] b callee_ext .size good_plt_tailcall_trusted, .-good_plt_tailcall_trusted .globl good_indirect_tailcall_trusted .type good_indirect_tailcall_trusted,@function good_indirect_tailcall_trusted: // CHECK-NOT: good_indirect_tailcall_trusted paciasp stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 autiasp ldr w2, [x30] autia x0, x1 br x0 .size good_indirect_tailcall_trusted, .-good_indirect_tailcall_trusted .globl good_direct_tailcall_no_clobber_multi_bb .type good_direct_tailcall_no_clobber_multi_bb,@function good_direct_tailcall_no_clobber_multi_bb: // CHECK-NOT: good_direct_tailcall_no_clobber_multi_bb b 1f 1: b callee .size good_direct_tailcall_no_clobber_multi_bb, .-good_direct_tailcall_no_clobber_multi_bb .globl good_indirect_tailcall_no_clobber_multi_bb .type good_indirect_tailcall_no_clobber_multi_bb,@function good_indirect_tailcall_no_clobber_multi_bb: // CHECK-NOT: good_indirect_tailcall_no_clobber_multi_bb autia x0, x1 b 1f 1: br x0 .size good_indirect_tailcall_no_clobber_multi_bb_multi_bb, .-good_indirect_tailcall_no_clobber_multi_bb_multi_bb .globl bad_direct_tailcall_not_auted_multi_bb .type bad_direct_tailcall_not_auted_multi_bb,@function bad_direct_tailcall_not_auted_multi_bb: // CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_not_auted_multi_bb, basic block {{[^,]+}}, at address // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 cbz x3, 1f autiasp ldr w2, [x30] 1: b callee .size bad_direct_tailcall_not_auted_multi_bb, .-bad_direct_tailcall_not_auted_multi_bb .globl bad_indirect_tailcall_not_auted_multi_bb .type bad_indirect_tailcall_not_auted_multi_bb,@function bad_indirect_tailcall_not_auted_multi_bb: // CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_not_auted_multi_bb, basic block {{[^,]+}}, at address // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: br x0 # UNKNOWN CONTROL FLOW // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 cbz x3, 1f autiasp ldr w2, [x30] 1: autia x0, x1 br x0 .size bad_indirect_tailcall_not_auted_multi_bb, .-bad_indirect_tailcall_not_auted_multi_bb .globl bad_direct_tailcall_untrusted_multi_bb .type bad_direct_tailcall_untrusted_multi_bb,@function bad_direct_tailcall_untrusted_multi_bb: // FPAC-NOT: bad_direct_tailcall_untrusted_multi_bb // NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL // NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are: // NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_direct_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp // NOFPAC-NEXT: The 1 instructions that leak the affected registers are: // NOFPAC-NEXT: 1. {{[0-9a-f]+}}: b callee # TAILCALL paciasp stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 autiasp cbz x3, 1f ldr w2, [x30] 1: b callee .size bad_direct_tailcall_untrusted_multi_bb, .-bad_direct_tailcall_untrusted_multi_bb .globl bad_indirect_tailcall_untrusted_multi_bb .type bad_indirect_tailcall_untrusted_multi_bb,@function bad_indirect_tailcall_untrusted_multi_bb: // FPAC-NOT: bad_indirect_tailcall_untrusted_multi_bb // NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: br x0 # UNKNOWN CONTROL FLOW // NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are: // NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp // NOFPAC-NEXT: The 0 instructions that leak the affected registers are: paciasp stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 autiasp cbz x3, 1f ldr w2, [x30] 1: autia x0, x1 br x0 .size bad_indirect_tailcall_untrusted_multi_bb, .-bad_indirect_tailcall_untrusted_multi_bb .globl good_direct_tailcall_trusted_multi_bb .type good_direct_tailcall_trusted_multi_bb,@function good_direct_tailcall_trusted_multi_bb: // CHECK-NOT: good_direct_tailcall_trusted_multi_bb paciasp stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 autiasp ldr w2, [x30] b 1f 1: b callee .size good_direct_tailcall_trusted_multi_bb, .-good_direct_tailcall_trusted_multi_bb .globl good_indirect_tailcall_trusted_multi_bb .type good_indirect_tailcall_trusted_multi_bb,@function good_indirect_tailcall_trusted_multi_bb: // CHECK-NOT: good_indirect_tailcall_trusted_multi_bb paciasp stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 autiasp ldr w2, [x30] b 1f 1: autia x0, x1 br x0 .size good_indirect_tailcall_trusted_multi_bb, .-good_indirect_tailcall_trusted_multi_bb .globl good_direct_tailcall_no_clobber_nocfg .type good_direct_tailcall_no_clobber_nocfg,@function good_direct_tailcall_no_clobber_nocfg: // CHECK-NOT: good_direct_tailcall_no_clobber_nocfg adr x3, 1f br x3 1: b callee .size good_direct_tailcall_no_clobber_nocfg, .-good_direct_tailcall_no_clobber_nocfg .globl good_plt_tailcall_no_clobber_nocfg .type good_plt_tailcall_no_clobber_nocfg,@function good_plt_tailcall_no_clobber_nocfg: // CHECK-NOT: good_plt_tailcall_no_clobber_nocfg adr x3, 1f br x3 1: b callee_ext .size good_plt_tailcall_no_clobber_nocfg, .-good_plt_tailcall_no_clobber_nocfg .globl good_indirect_tailcall_no_clobber_nocfg .type good_indirect_tailcall_no_clobber_nocfg,@function good_indirect_tailcall_no_clobber_nocfg: // CHECK-NOT: good_indirect_tailcall_no_clobber_nocfg adr x3, 1f br x3 1: autia x0, x1 br x0 .size good_indirect_tailcall_no_clobber_nocfg, .-good_indirect_tailcall_no_clobber_nocfg .globl bad_direct_tailcall_not_auted_nocfg .type bad_direct_tailcall_not_auted_nocfg,@function bad_direct_tailcall_not_auted_nocfg: // CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_not_auted_nocfg, at address // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 stp x29, x30, [sp, #-0x10]! adr x3, 1f br x3 1: ldp x29, x30, [sp], #0x10 b callee .size bad_direct_tailcall_not_auted_nocfg, .-bad_direct_tailcall_not_auted_nocfg .globl bad_plt_tailcall_not_auted_nocfg .type bad_plt_tailcall_not_auted_nocfg,@function bad_plt_tailcall_not_auted_nocfg: // FIXME: Calls via PLT are disassembled incorrectly. Nevertheless, they are // still detected as tail calls. // CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_plt_tailcall_not_auted_nocfg, at address // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b bad_indirect_tailcall_not_auted_nocfg # TAILCALL // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 stp x29, x30, [sp, #-0x10]! adr x3, 1f br x3 1: ldp x29, x30, [sp], #0x10 b callee_ext .size bad_plt_tailcall_not_auted_nocfg, .-bad_plt_tailcall_not_auted_nocfg .globl bad_indirect_tailcall_not_auted_nocfg .type bad_indirect_tailcall_not_auted_nocfg,@function bad_indirect_tailcall_not_auted_nocfg: // Known false positive: ignoring UNKNOWN CONTROL FLOW without CFG. // CHECK-NOT: bad_indirect_tailcall_not_auted_nocfg stp x29, x30, [sp, #-0x10]! adr x3, 1f br x3 1: ldp x29, x30, [sp], #0x10 autia x0, x1 br x0 .size bad_indirect_tailcall_not_auted_nocfg, .-bad_indirect_tailcall_not_auted_nocfg .globl bad_direct_tailcall_untrusted_nocfg .type bad_direct_tailcall_untrusted_nocfg,@function bad_direct_tailcall_untrusted_nocfg: // FPAC-NOT: bad_direct_tailcall_untrusted_nocfg // NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_untrusted_nocfg, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL // NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are: // NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_direct_tailcall_untrusted_nocfg, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp // NOFPAC-NEXT: The 1 instructions that leak the affected registers are: // NOFPAC-NEXT: 1. {{[0-9a-f]+}}: b callee # TAILCALL paciasp stp x29, x30, [sp, #-0x10]! adr x3, 1f br x3 1: ldp x29, x30, [sp], #0x10 autiasp b callee .size bad_direct_tailcall_untrusted_nocfg, .-bad_direct_tailcall_untrusted_nocfg .globl bad_plt_tailcall_untrusted_nocfg .type bad_plt_tailcall_untrusted_nocfg,@function bad_plt_tailcall_untrusted_nocfg: // FIXME: Calls via PLT are disassembled incorrectly. Nevertheless, they are // still detected as tail calls. // FPAC-NOT: bad_plt_tailcall_untrusted_nocfg // NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_plt_tailcall_untrusted_nocfg, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted_nocfg # TAILCALL // NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are: // NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_plt_tailcall_untrusted_nocfg, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp // NOFPAC-NEXT: The 1 instructions that leak the affected registers are: // NOFPAC-NEXT: 1. {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted_nocfg # TAILCALL paciasp stp x29, x30, [sp, #-0x10]! adr x3, 1f br x3 1: ldp x29, x30, [sp], #0x10 autiasp b callee_ext .size bad_plt_tailcall_untrusted_nocfg, .-bad_plt_tailcall_untrusted_nocfg .globl bad_indirect_tailcall_untrusted_nocfg .type bad_indirect_tailcall_untrusted_nocfg,@function bad_indirect_tailcall_untrusted_nocfg: // Known false negative: ignoring UNKNOWN CONTROL FLOW without CFG. // Authentication oracle is found by a generic checker, though. // FPAC-NOT: bad_indirect_tailcall_untrusted_nocfg // NOFPAC-NOT: untrusted link register{{.*}}bad_indirect_tailcall_untrusted_nocfg // NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted_nocfg, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp // NOFPAC-NEXT: The 0 instructions that leak the affected registers are: // NOFPAC-NOT: untrusted link register{{.*}}bad_indirect_tailcall_untrusted_nocfg paciasp stp x29, x30, [sp, #-0x10]! adr x3, 1f br x3 1: ldp x29, x30, [sp], #0x10 autiasp autia x0, x1 br x0 .size bad_indirect_tailcall_untrusted_nocfg, .-bad_indirect_tailcall_untrusted_nocfg .globl good_direct_tailcall_trusted_nocfg .type good_direct_tailcall_trusted_nocfg,@function good_direct_tailcall_trusted_nocfg: // CHECK-NOT: good_direct_tailcall_trusted_nocfg paciasp stp x29, x30, [sp, #-0x10]! adr x3, 1f br x3 1: ldp x29, x30, [sp], #0x10 autiasp ldr w2, [x30] b callee .size good_direct_tailcall_trusted_nocfg, .-good_direct_tailcall_trusted_nocfg .globl good_plt_tailcall_trusted_nocfg .type good_plt_tailcall_trusted_nocfg,@function good_plt_tailcall_trusted_nocfg: // CHECK-NOT: good_plt_tailcall_trusted_nocfg paciasp stp x29, x30, [sp, #-0x10]! adr x3, 1f br x3 1: ldp x29, x30, [sp], #0x10 autiasp ldr w2, [x30] b callee_ext .size good_plt_tailcall_trusted_nocfg, .-good_plt_tailcall_trusted_nocfg .globl good_indirect_tailcall_trusted_nocfg .type good_indirect_tailcall_trusted_nocfg,@function good_indirect_tailcall_trusted_nocfg: // CHECK-NOT: good_indirect_tailcall_trusted_nocfg paciasp stp x29, x30, [sp, #-0x10]! adr x3, 1f br x3 1: ldp x29, x30, [sp], #0x10 autiasp ldr w2, [x30] autia x0, x1 br x0 .size good_indirect_tailcall_trusted_nocfg, .-good_indirect_tailcall_trusted_nocfg // Check Armv8.3-a fused auth+branch instructions. .globl good_indirect_tailcall_no_clobber_v83 .type good_indirect_tailcall_no_clobber_v83,@function good_indirect_tailcall_no_clobber_v83: // CHECK-NOT: good_indirect_tailcall_no_clobber_v83 braa x0, x1 .size good_indirect_tailcall_no_clobber_v83, .-good_indirect_tailcall_no_clobber_v83 .globl bad_indirect_tailcall_untrusted_v83 .type bad_indirect_tailcall_untrusted_v83,@function bad_indirect_tailcall_untrusted_v83: // FPAC-NOT: bad_indirect_tailcall_untrusted_v83 // NOFPAC-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_untrusted_v83, basic block {{[^,]+}}, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: braa x0, x1 # TAILCALL // NOFPAC-NEXT: The 0 instructions that write to the affected registers after any authentication are: // NOFPAC-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted_v83, basic block {{[^,]+}}, at address // NOFPAC-NEXT: The instruction is {{[0-9a-f]+}}: autiasp // NOFPAC-NEXT: The 1 instructions that leak the affected registers are: // NOFPAC-NEXT: 1. {{[0-9a-f]+}}: braa x0, x1 # TAILCALL // NOFPAC-NEXT: This happens in the following basic block: // NOFPAC-NEXT: {{[0-9a-f]+}}: paciasp // NOFPAC-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! // NOFPAC-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 // NOFPAC-NEXT: {{[0-9a-f]+}}: autiasp // NOFPAC-NEXT: {{[0-9a-f]+}}: braa x0, x1 # TAILCALL paciasp stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 autiasp braa x0, x1 .size bad_indirect_tailcall_untrusted_v83, .-bad_indirect_tailcall_untrusted_v83 // Make sure ELF entry function does not generate false positive reports. // Additionally, check that the correct entry point is read from ELF header. .globl _start .type _start,@function _start: // CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function _start, basic block {{[^,]+}}, at address // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: // CHECK-NEXT: 1. {{[0-9a-f]+}}: mov x30, #0x0 // CHECK-NEXT: This happens in the following basic block: // CHECK-NEXT: {{[0-9a-f]+}}: mov x30, #0x0 // CHECK-NEXT: {{[0-9a-f]+}}: b callee # TAILCALL mov x30, #0 b callee .size _start, .-_start .globl _custom_start .type _custom_start,@function _custom_start: // CHECK-NOT: _custom_start mov x30, #0 b callee .size _custom_start, .-_custom_start // Test two issues being reported for the same instruction. .globl bad_non_protected_indirect_tailcall_not_auted .type bad_non_protected_indirect_tailcall_not_auted,@function bad_non_protected_indirect_tailcall_not_auted: // CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_non_protected_indirect_tailcall_not_auted, basic block {{[^,]+}}, at address // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: br x0 # TAILCALL // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 // CHECK-NEXT: This happens in the following basic block: // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 // CHECK-NEXT: {{[0-9a-f]+}}: ldr x0, [x1] // CHECK-NEXT: {{[0-9a-f]+}}: br x0 # TAILCALL // CHECK-LABEL: GS-PAUTH: non-protected call found in function bad_non_protected_indirect_tailcall_not_auted, basic block {{[^,]+}}, at address // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: br x0 # TAILCALL // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldr x0, [x1] // CHECK-NEXT: This happens in the following basic block: // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 // CHECK-NEXT: {{[0-9a-f]+}}: ldr x0, [x1] // CHECK-NEXT: {{[0-9a-f]+}}: br x0 # TAILCALL stp x29, x30, [sp, #-0x10]! ldp x29, x30, [sp], #0x10 ldr x0, [x1] br x0 .size bad_non_protected_indirect_tailcall_not_auted, .-bad_non_protected_indirect_tailcall_not_auted .globl main .type main,@function main: mov x0, 0 ret .size main, .-main