[llvm] [BOLT] Gadget scanner: detect authentication oracles (PR #135663)
Anatoly Trosinenko via llvm-commits
llvm-commits at lists.llvm.org
Wed May 28 10:07:54 PDT 2025
================
@@ -0,0 +1,739 @@
+// RUN: %clang %cflags -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
+
+// The detection of compiler-generated explicit pointer checks is tested in
+// gs-pauth-address-checks.s, for that reason only test here "dummy-load" and
+// "high-bits-notbi" checkers, as the shortest examples of checkers that are
+// detected per-instruction and per-BB.
+
+// PACRET-NOT: authentication oracle found in function
+
+ .text
+
+ .type sym, at function
+sym:
+ ret
+ .size sym, .-sym
+
+ .globl callee
+ .type callee, at function
+callee:
+ ret
+ .size callee, .-callee
+
+ .globl good_ret
+ .type good_ret, at function
+good_ret:
+// CHECK-NOT: good_ret
+ autia x0, x1
+ ret x0
+ .size good_ret, .-good_ret
+
+ .globl good_call
+ .type good_call, at function
+good_call:
+// CHECK-NOT: good_call
+ paciasp
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+
+ autia x0, x1
+ blr x0
+
+ ldp x29, x30, [sp], #16
+ autiasp
+ ret
+ .size good_call, .-good_call
+
+ .globl good_branch
+ .type good_branch, at function
+good_branch:
+// CHECK-NOT: good_branch
+ autia x0, x1
+ br x0
+ .size good_branch, .-good_branch
+
+ .globl good_load_other_reg
+ .type good_load_other_reg, at function
+good_load_other_reg:
+// CHECK-NOT: good_load_other_reg
+ autia x0, x1
+ ldr x2, [x0]
+ ret
+ .size good_load_other_reg, .-good_load_other_reg
+
+ .globl good_load_same_reg
+ .type good_load_same_reg, at function
+good_load_same_reg:
+// CHECK-NOT: good_load_same_reg
+ autia x0, x1
+ ldr x0, [x0]
+ ret
+ .size good_load_same_reg, .-good_load_same_reg
+
+ .globl good_explicit_check
+ .type good_explicit_check, at function
+good_explicit_check:
+// CHECK-NOT: good_explicit_check
+ autia x0, x1
+ eor x16, x0, x0, lsl #1
+ tbz x16, #62, 1f
+ brk 0x1234
+1:
+ ret
+ .size good_explicit_check, .-good_explicit_check
+
+ .globl bad_unchecked
+ .type bad_unchecked, at function
+bad_unchecked:
+// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unchecked, basic block {{[^,]+}}, at address
+// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
+// CHECK-NEXT: The 0 instructions that leak the affected registers are:
+ autia x0, x1
+ ret
+ .size bad_unchecked, .-bad_unchecked
+
+ .globl bad_leaked_to_subroutine
+ .type bad_leaked_to_subroutine, at function
+bad_leaked_to_subroutine:
+// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_leaked_to_subroutine, basic block {{[^,]+}}, at address
+// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
+// CHECK-NEXT: The 1 instructions that leak the affected registers are:
+// CHECK-NEXT: 1. {{[0-9a-f]+}}: bl callee
+// 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]+}}: mov x29, sp
+// CHECK-NEXT: {{[0-9a-f]+}}: autia x0, x1
+// CHECK-NEXT: {{[0-9a-f]+}}: bl callee
+// CHECK-NEXT: {{[0-9a-f]+}}: ldr x2, [x0]
+// CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10
+// CHECK-NEXT: {{[0-9a-f]+}}: autiasp
+// CHECK-NEXT: {{[0-9a-f]+}}: ret
+ paciasp
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+
+ autia x0, x1
+ bl callee
+ ldr x2, [x0]
+
+ ldp x29, x30, [sp], #16
+ autiasp
+ ret
+ .size bad_leaked_to_subroutine, .-bad_leaked_to_subroutine
+
+ .globl bad_unknown_usage_read
+ .type bad_unknown_usage_read, at function
+bad_unknown_usage_read:
+// CHECK-LABEL: GS-PAUTH: authentication oracle found in function bad_unknown_usage_read, basic block {{[^,]+}}, at address
+// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
+// CHECK-NEXT: The 1 instructions that leak the affected registers are:
+// CHECK-NEXT: 1. {{[0-9a-f]+}}: mul x3, x0, x1
+// CHECK-NEXT: This happens in the following basic block:
+// CHECK-NEXT: {{[0-9a-f]+}}: autia x0, x1
+// CHECK-NEXT: {{[0-9a-f]+}}: mul x3, x0, x1
+// CHECK-NEXT: {{[0-9a-f]+}}: ldr x2, [x0]
+// CHECK-NEXT: {{[0-9a-f]+}}: ret
+ autia x0, x1
+ mul x3, x0, x1
+ ldr x2, [x0]
----------------
atrosinenko wrote:
Added a few more test cases based on this discussion. Turned out, false negative are possible, if no RET instructions are reachable from the instruction to be reported as an authentication oracle. Added a FIXME so far, as it probably deserves a separate PR...
https://github.com/llvm/llvm-project/pull/135663
More information about the llvm-commits
mailing list