blob: 2d3c2f1a632ca30d87318f524725f5f77ed16e30 [file] [log] [blame]
// RUN: %clang %cflags -Wl,--entry=_custom_start -march=armv8.3-a %s -o %t.exe
// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck -check-prefix=PACRET %s
// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s
// PACRET-NOT: untrusted link register found before tail call
.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:
// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_untrusted, basic block {{[^,]+}}, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_direct_tailcall_untrusted, basic block {{[^,]+}}, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
// CHECK-NEXT: 1. {{[0-9a-f]+}}: b callee # TAILCALL
// CHECK-NEXT: This happens in the following basic block:
// CHECK-NEXT: {{[0-9a-f]+}}: paciasp
// 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]+}}: autiasp
// CHECK-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.
// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_plt_tailcall_untrusted, basic block {{[^,]+}}, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted # TAILCALL
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_plt_tailcall_untrusted, basic block {{[^,]+}}, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
// CHECK-NEXT: 1. {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted # TAILCALL
// CHECK-NEXT: This happens in the following basic block:
// CHECK-NEXT: {{[0-9a-f]+}}: paciasp
// 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]+}}: autiasp
// CHECK-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:
// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_untrusted, basic block {{[^,]+}}, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: br x0 # TAILCALL
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted, basic block {{[^,]+}}, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
// CHECK-NEXT: 1. {{[0-9a-f]+}}: br x0 # TAILCALL
// CHECK-NEXT: This happens in the following basic block:
// CHECK-NEXT: {{[0-9a-f]+}}: paciasp
// 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]+}}: autiasp
// CHECK-NEXT: {{[0-9a-f]+}}: autia x0, x1
// CHECK-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:
// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_direct_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
// CHECK-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:
// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: br x0 # UNKNOWN CONTROL FLOW
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted_multi_bb, basic block {{[^,]+}}, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
// CHECK-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:
// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_direct_tailcall_untrusted_nocfg, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b callee # TAILCALL
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_direct_tailcall_untrusted_nocfg, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
// CHECK-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.
// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_plt_tailcall_untrusted_nocfg, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: b bad_indirect_tailcall_untrusted_nocfg # TAILCALL
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_plt_tailcall_untrusted_nocfg, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
// CHECK-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.
// CHECK-NOT: untrusted link register{{.*}}bad_indirect_tailcall_untrusted_nocfg
// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted_nocfg, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
// CHECK-NEXT: The 0 instructions that leak the affected registers are:
// CHECK-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:
// CHECK-LABEL: GS-PAUTH: untrusted link register found before tail call in function bad_indirect_tailcall_untrusted_v83, basic block {{[^,]+}}, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: braa x0, x1 # TAILCALL
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_indirect_tailcall_untrusted_v83, basic block {{[^,]+}}, at address
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autiasp
// CHECK-NEXT: The 1 instructions that leak the affected registers are:
// CHECK-NEXT: 1. {{[0-9a-f]+}}: braa x0, x1 # TAILCALL
// CHECK-NEXT: This happens in the following basic block:
// CHECK-NEXT: {{[0-9a-f]+}}: paciasp
// 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]+}}: autiasp
// CHECK-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