After a label in a function without CFG information, use a reasonably pessimistic estimation of register state (assume that any register that can be clobbered in this function was actually clobbered) instead of the most pessimistic "all registers are unsafe". This is the same estimation as used by the dataflow variant of the analysis when the preceding instruction is not known for sure. Without this, leaf functions without CFG information are likely to have false positive reports about non-protected return instructions, as 1) LR is unlikely to be signed and authenticated in a leaf function and 2) LR is likely to be used by a return instruction near the end of the function and 3) the register state is likely to be reset at least once during the linear scan through the function
900 lines
31 KiB
ArmAsm
900 lines
31 KiB
ArmAsm
// RUN: %clang %cflags -march=armv9.5-a+pauth-lr -mbranch-protection=pac-ret %s %p/../../Inputs/asm_main.c -o %t.exe
|
|
// RUN: llvm-bolt-binary-analysis --scanners=pacret %t.exe 2>&1 | FileCheck %s
|
|
|
|
.text
|
|
|
|
.globl f1
|
|
.type f1,@function
|
|
f1:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
// autiasp
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f1, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f1, .-f1
|
|
|
|
|
|
.globl f_intermediate_overwrite1
|
|
.type f_intermediate_overwrite1,@function
|
|
f_intermediate_overwrite1:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
autiasp
|
|
ldp x29, x30, [sp], #16
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_intermediate_overwrite1, basic block {{[0-9a-zA-Z.]+}}
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autiasp
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_intermediate_overwrite1, .-f_intermediate_overwrite1
|
|
|
|
.globl f_intermediate_overwrite2
|
|
.type f_intermediate_overwrite2,@function
|
|
f_intermediate_overwrite2:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autiasp
|
|
mov x30, x0
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_intermediate_overwrite2, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mov x30, x0
|
|
// CHECK-NEXT: This happens in the following basic block:
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autiasp
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: mov x30, x0
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_intermediate_overwrite2, .-f_intermediate_overwrite2
|
|
|
|
.globl f_intermediate_read
|
|
.type f_intermediate_read,@function
|
|
f_intermediate_read:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autiasp
|
|
mov x0, x30
|
|
// CHECK-NOT: function f_intermediate_read
|
|
ret
|
|
.size f_intermediate_read, .-f_intermediate_read
|
|
|
|
.globl f_intermediate_overwrite3
|
|
.type f_intermediate_overwrite3,@function
|
|
f_intermediate_overwrite3:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autiasp
|
|
mov w30, w0
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_intermediate_overwrite3, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mov w30, w0
|
|
// CHECK-NEXT: This happens in the following basic block:
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autiasp
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: mov w30, w0
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_intermediate_overwrite3, .-f_intermediate_overwrite3
|
|
|
|
.globl f_nonx30_ret
|
|
.type f_nonx30_ret,@function
|
|
f_nonx30_ret:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
mov x16, x30
|
|
autiasp
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_nonx30_ret, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret x16
|
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mov x16, x30
|
|
// CHECK-NEXT: This happens in the following basic block:
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: mov x16, x30
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autiasp
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret x16
|
|
ret x16
|
|
.size f_nonx30_ret, .-f_nonx30_ret
|
|
|
|
.globl f_nonx30_ret_ok
|
|
.type f_nonx30_ret_ok,@function
|
|
f_nonx30_ret_ok:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
ldp x29, x30, [sp], #16
|
|
autiasp
|
|
mov x16, x30
|
|
// CHECK-NOT: function f_nonx30_ret_ok
|
|
ret x16
|
|
.size f_nonx30_ret_ok, .-f_nonx30_ret_ok
|
|
|
|
.globl f_detect_clobbered_x30_passed_to_other
|
|
.type f_detect_clobbered_x30_passed_to_other,@function
|
|
f_detect_clobbered_x30_passed_to_other:
|
|
str x30, [sp]
|
|
ldr x30, [sp]
|
|
// FIXME: Ideally, the pac-ret scanner would report on the following instruction, which
|
|
// performs a tail call, that x30 might be attacker-controlled.
|
|
// CHECK-NOT: function f_detect_clobbered_x30_passed_to_other
|
|
b f_tail_called
|
|
.size f_detect_clobbered_x30_passed_to_other, .-f_detect_clobbered_x30_passed_to_other
|
|
|
|
.globl f_tail_called
|
|
.type f_tail_called,@function
|
|
f_tail_called:
|
|
ret
|
|
.size f_tail_called, .-f_tail_called
|
|
|
|
.globl f_nonx30_ret_non_auted
|
|
.type f_nonx30_ret_non_auted,@function
|
|
f_nonx30_ret_non_auted:
|
|
// x1 is neither authenticated nor implicitly considered safe at function entry.
|
|
// Note that we assume it's fine for x30 to not be authenticated before
|
|
// returning to, as assuming that x30 is not attacker controlled at function
|
|
// entry is part (implicitly) of the pac-ret hardening scheme.
|
|
//
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_nonx30_ret_non_auted, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
|
|
ret x1
|
|
.size f_nonx30_ret_non_auted, .-f_nonx30_ret_non_auted
|
|
|
|
|
|
.globl f_callclobbered_x30
|
|
.type f_callclobbered_x30,@function
|
|
f_callclobbered_x30:
|
|
bl g
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_callclobbered_x30, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: bl
|
|
ret
|
|
.size f_callclobbered_x30, .-f_callclobbered_x30
|
|
|
|
.globl f_callclobbered_calleesaved
|
|
.type f_callclobbered_calleesaved,@function
|
|
f_callclobbered_calleesaved:
|
|
bl g
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_callclobbered_calleesaved, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret x19
|
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: bl
|
|
// x19, according to the Arm ABI (AAPCS) is a callee-saved register.
|
|
// Therefore, if function g respects the AAPCS, it should not write
|
|
// anything to x19. However, we can't know whether function g actually
|
|
// does respect the AAPCS rules, so the scanner should assume x19 can
|
|
// get overwritten, and report a gadget if the code does not properly
|
|
// deal with that.
|
|
// Furthermore, there's a good chance that callee-saved registers have
|
|
// been saved on the stack at some point during execution of the callee,
|
|
// and so should be considered as potentially modified by an
|
|
// attacker/written to.
|
|
ret x19
|
|
.size f_callclobbered_calleesaved, .-f_callclobbered_calleesaved
|
|
|
|
.globl f_unreachable_instruction
|
|
.type f_unreachable_instruction,@function
|
|
f_unreachable_instruction:
|
|
// CHECK-LABEL: GS-PAUTH: Warning: possibly imprecise CFG, the analysis quality may be degraded in this function. According to BOLT, unreachable code is found in function f_unreachable_instruction, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: add x0, x1, x2
|
|
// CHECK-NOT: instructions that write to the affected registers after any authentication are:
|
|
b 1f
|
|
add x0, x1, x2
|
|
1:
|
|
ret
|
|
.size f_unreachable_instruction, .-f_unreachable_instruction
|
|
|
|
// Without CFG, the state is reset at labels, assuming every register that can
|
|
// be clobbered in the function was actually clobbered.
|
|
|
|
.globl lr_untouched_nocfg
|
|
.type lr_untouched_nocfg,@function
|
|
lr_untouched_nocfg:
|
|
// CHECK-NOT: lr_untouched_nocfg
|
|
adr x2, 1f
|
|
br x2
|
|
1:
|
|
ret
|
|
.size lr_untouched_nocfg, .-lr_untouched_nocfg
|
|
|
|
.globl lr_clobbered_nocfg
|
|
.type lr_clobbered_nocfg,@function
|
|
lr_clobbered_nocfg:
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function lr_clobbered_nocfg, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are:
|
|
adr x2, 1f
|
|
br x2
|
|
1:
|
|
b 2f
|
|
bl g // never executed, but affects the expected worst-case scenario
|
|
2:
|
|
ret
|
|
.size lr_clobbered_nocfg, .-lr_clobbered_nocfg
|
|
|
|
/// Now do a basic sanity check on every different Authentication instruction:
|
|
|
|
.globl f_autiasp
|
|
.type f_autiasp,@function
|
|
f_autiasp:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autiasp
|
|
// CHECK-NOT: function f_autiasp
|
|
ret
|
|
.size f_autiasp, .-f_autiasp
|
|
|
|
.globl f_autibsp
|
|
.type f_autibsp,@function
|
|
f_autibsp:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autibsp
|
|
// CHECK-NOT: function f_autibsp
|
|
ret
|
|
.size f_autibsp, .-f_autibsp
|
|
|
|
.globl f_autiaz
|
|
.type f_autiaz,@function
|
|
f_autiaz:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autiaz
|
|
// CHECK-NOT: function f_autiaz
|
|
ret
|
|
.size f_autiaz, .-f_autiaz
|
|
|
|
.globl f_autibz
|
|
.type f_autibz,@function
|
|
f_autibz:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autibz
|
|
// CHECK-NOT: function f_autibz
|
|
ret
|
|
.size f_autibz, .-f_autibz
|
|
|
|
.globl f_autia1716
|
|
.type f_autia1716,@function
|
|
f_autia1716:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autia1716
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autia1716, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autia1716
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_autia1716, .-f_autia1716
|
|
|
|
.globl f_autib1716
|
|
.type f_autib1716,@function
|
|
f_autib1716:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autib1716
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autib1716, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autib1716
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_autib1716, .-f_autib1716
|
|
|
|
.globl f_autiax12
|
|
.type f_autiax12,@function
|
|
f_autiax12:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autia x12, sp
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autiax12, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autia x12, sp
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_autiax12, .-f_autiax12
|
|
|
|
.globl f_autibx12
|
|
.type f_autibx12,@function
|
|
f_autibx12:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autib x12, sp
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autibx12, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autib x12, sp
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_autibx12, .-f_autibx12
|
|
|
|
.globl f_autiax30
|
|
.type f_autiax30,@function
|
|
f_autiax30:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autia x30, sp
|
|
// CHECK-NOT: function f_autiax30
|
|
ret
|
|
.size f_autiax30, .-f_autiax30
|
|
|
|
.globl f_autibx30
|
|
.type f_autibx30,@function
|
|
f_autibx30:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autib x30, sp
|
|
// CHECK-NOT: function f_autibx30
|
|
ret
|
|
.size f_autibx30, .-f_autibx30
|
|
|
|
|
|
.globl f_autdax12
|
|
.type f_autdax12,@function
|
|
f_autdax12:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autda x12, sp
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autdax12, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autda x12, sp
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_autdax12, .-f_autdax12
|
|
|
|
.globl f_autdbx12
|
|
.type f_autdbx12,@function
|
|
f_autdbx12:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autdb x12, sp
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autdbx12, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autdb x12, sp
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_autdbx12, .-f_autdbx12
|
|
|
|
.globl f_autdax30
|
|
.type f_autdax30,@function
|
|
f_autdax30:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autda x30, sp
|
|
// CHECK-NOT: function f_autdax30
|
|
ret
|
|
.size f_autdax30, .-f_autdax30
|
|
|
|
.globl f_autdbx30
|
|
.type f_autdbx30,@function
|
|
f_autdbx30:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autdb x30, sp
|
|
// CHECK-NOT: function f_autdbx30
|
|
ret
|
|
.size f_autdbx30, .-f_autdbx30
|
|
|
|
|
|
.globl f_autizax12
|
|
.type f_autizax12,@function
|
|
f_autizax12:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autiza x12
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autizax12, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autiza x12
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_autizax12, .-f_autizax12
|
|
|
|
.globl f_autizbx12
|
|
.type f_autizbx12,@function
|
|
f_autizbx12:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autizb x12
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autizbx12, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autizb x12
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_autizbx12, .-f_autizbx12
|
|
|
|
.globl f_autizax30
|
|
.type f_autizax30,@function
|
|
f_autizax30:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autiza x30
|
|
// CHECK-NOT: function f_autizax30
|
|
ret
|
|
.size f_autizax30, .-f_autizax30
|
|
|
|
.globl f_autizbx30
|
|
.type f_autizbx30,@function
|
|
f_autizbx30:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autizb x30
|
|
// CHECK-NOT: function f_autizbx30
|
|
ret
|
|
.size f_autizbx30, .-f_autizbx30
|
|
|
|
|
|
.globl f_autdzax12
|
|
.type f_autdzax12,@function
|
|
f_autdzax12:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autdza x12
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autdzax12, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autdza x12
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_autdzax12, .-f_autdzax12
|
|
|
|
.globl f_autdzbx12
|
|
.type f_autdzbx12,@function
|
|
f_autdzbx12:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autdzb x12
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autdzbx12, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autdzb x12
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_autdzbx12, .-f_autdzbx12
|
|
|
|
.globl f_autdzax30
|
|
.type f_autdzax30,@function
|
|
f_autdzax30:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autdza x30
|
|
// CHECK-NOT: function f_autdzax30
|
|
ret
|
|
.size f_autdzax30, .-f_autdzax30
|
|
|
|
.globl f_autdzbx30
|
|
.type f_autdzbx30,@function
|
|
f_autdzbx30:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autdzb x30
|
|
// CHECK-NOT: function f_autdzbx30
|
|
ret
|
|
.size f_autdzbx30, .-f_autdzbx30
|
|
|
|
.globl f_retaa
|
|
.type f_retaa,@function
|
|
f_retaa:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
// CHECK-NOT: function f_retaa
|
|
retaa
|
|
.size f_retaa, .-f_retaa
|
|
|
|
.globl f_retab
|
|
.type f_retab,@function
|
|
f_retab:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
// CHECK-NOT: function f_retab
|
|
retab
|
|
.size f_retab, .-f_retab
|
|
|
|
.globl f_eretaa
|
|
.type f_eretaa,@function
|
|
f_eretaa:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
// CHECK-LABEL: GS-PAUTH: Warning: pac-ret analysis could not analyze this return instruction in function f_eretaa, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: eretaa
|
|
eretaa
|
|
.size f_eretaa, .-f_eretaa
|
|
|
|
.globl f_eretab
|
|
.type f_eretab,@function
|
|
f_eretab:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
// CHECK-LABEL: GS-PAUTH: Warning: pac-ret analysis could not analyze this return instruction in function f_eretab, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: eretab
|
|
eretab
|
|
.size f_eretab, .-f_eretab
|
|
|
|
.globl f_eret
|
|
.type f_eret,@function
|
|
f_eret:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
// CHECK-LABEL: GS-PAUTH: Warning: pac-ret analysis could not analyze this return instruction in function f_eret, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: eret
|
|
eret
|
|
.size f_eret, .-f_eret
|
|
|
|
.globl f_movx30reg
|
|
.type f_movx30reg,@function
|
|
f_movx30reg:
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_movx30reg, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mov x30, x22
|
|
// CHECK-NEXT: This happens in the following basic block:
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: mov x30, x22
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
mov x30, x22
|
|
ret
|
|
.size f_movx30reg, .-f_movx30reg
|
|
|
|
.globl f_autiasppci
|
|
.type f_autiasppci,@function
|
|
f_autiasppci:
|
|
0:
|
|
pacnbiasppc
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autiasppc 0b
|
|
// CHECK-NOT: function f_autiasppci
|
|
ret
|
|
.size f_autiasppci, .-f_autiasppci
|
|
|
|
.globl f_autibsppci
|
|
.type f_autibsppci,@function
|
|
f_autibsppci:
|
|
0:
|
|
pacnbibsppc
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autibsppc 0b
|
|
// CHECK-NOT: function f_autibsppci
|
|
ret
|
|
.size f_autibsppci, .-f_autibsppci
|
|
|
|
.globl f_autiasppcr
|
|
.type f_autiasppcr,@function
|
|
|
|
f_autiasppcr:
|
|
0:
|
|
pacnbiasppc
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
adr x28, 0b
|
|
autiasppcr x28
|
|
// CHECK-NOT: function f_autiasppcr
|
|
ret
|
|
.size f_autiasppcr, .-f_autiasppcr
|
|
|
|
f_autibsppcr:
|
|
0:
|
|
pacnbibsppc
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
adr x28, 0b
|
|
autibsppcr x28
|
|
// CHECK-NOT: function f_autibsppcr
|
|
ret
|
|
.size f_autibsppcr, .-f_autibsppcr
|
|
|
|
.globl f_retaasppci
|
|
.type f_retaasppci,@function
|
|
f_retaasppci:
|
|
0:
|
|
pacnbiasppc
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
// CHECK-NOT: function f_retaasppci
|
|
retaasppc 0b
|
|
.size f_retaasppci, .-f_retaasppci
|
|
|
|
.globl f_retabsppci
|
|
.type f_retabsppci,@function
|
|
f_retabsppci:
|
|
0:
|
|
pacnbibsppc
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
// CHECK-NOT: function f_retabsppci
|
|
retabsppc 0b
|
|
.size f_retabsppci, .-f_retabsppci
|
|
|
|
.globl f_retaasppcr
|
|
.type f_retaasppcr,@function
|
|
|
|
f_retaasppcr:
|
|
0:
|
|
pacnbiasppc
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
adr x28, 0b
|
|
// CHECK-NOT: function f_retaasppcr
|
|
retaasppcr x28
|
|
.size f_retaasppcr, .-f_retaasppcr
|
|
|
|
f_retabsppcr:
|
|
0:
|
|
pacnbibsppc
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
adr x28, 0b
|
|
// CHECK-NOT: function f_retabsppcr
|
|
retabsppcr x28
|
|
.size f_retabsppcr, .-f_retabsppcr
|
|
|
|
.globl f_autia171615
|
|
.type f_autia171615,@function
|
|
f_autia171615:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autia171615
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autia171615, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autia171615
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_autia171615, .-f_autia171615
|
|
|
|
.globl f_autib171615
|
|
.type f_autib171615,@function
|
|
f_autib171615:
|
|
paciasp
|
|
stp x29, x30, [sp, #-16]!
|
|
mov x29, sp
|
|
bl g
|
|
add x0, x0, #3
|
|
ldp x29, x30, [sp], #16
|
|
autib171615
|
|
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autib171615, basic block {{[0-9a-zA-Z.]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret
|
|
// 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]+}}: add x0, x0, #0x3
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: autib171615
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
ret
|
|
.size f_autib171615, .-f_autib171615
|
|
|