[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: Detect address materialization and arithmetics (PR #132540)

2025-04-05 Thread Jacob Bramley via llvm-branch-commits


@@ -0,0 +1,228 @@
+// RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe
+// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s
+
+// Test various patterns that should or should not be considered safe
+// materialization of PC-relative addresses.
+//
+// Note that while "instructions that write to the affected registers"
+// section of the report is still technically correct, it does not necessarily
+// mentions the instructions that are used incorrectly.
+//
+// FIXME: Switch to PAC* instructions instead of indirect tail call for testing
+//if a register is considered safe when detection of signing oracles is
+//implemented, as it is more traditional usage of PC-relative 
constants.
+//Moreover, using PAC instructions would improve test robustness, as
+//handling of *calls* can be influenced by what BOLT classifies as a
+//tail call, for example.
+
+.text
+

jacobbramley wrote:

I don't think there are any tests for `sub`. I doubt that it's likely to be 
much different from `add`, but it's probably worth having one case.

https://github.com/llvm/llvm-project/pull/132540
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: Detect address materialization and arithmetics (PR #132540)

2025-03-26 Thread Jacob Bramley via llvm-branch-commits


@@ -0,0 +1,228 @@
+// RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe
+// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s
+
+// Test various patterns that should or should not be considered safe
+// materialization of PC-relative addresses.
+//
+// Note that while "instructions that write to the affected registers"
+// section of the report is still technically correct, it does not necessarily
+// mentions the instructions that are used incorrectly.
+//
+// FIXME: Switch to PAC* instructions instead of indirect tail call for testing
+//if a register is considered safe when detection of signing oracles is
+//implemented, as it is more traditional usage of PC-relative 
constants.
+//Moreover, using PAC instructions would improve test robustness, as
+//handling of *calls* can be influenced by what BOLT classifies as a
+//tail call, for example.
+
+.text
+
+// Define a function that is reachable by ADR instruction.
+.type   sym,@function
+sym:
+ret
+.size   sym, .-sym
+
+.globl  good_adr
+.type   good_adr,@function
+good_adr:
+// CHECK-NOT: good_adr
+adr x0, sym
+br  x0
+.size   good_adr, .-good_adr
+
+.globl  good_adrp
+.type   good_adrp,@function
+good_adrp:
+// CHECK-NOT: good_adrp
+adrpx0, sym
+br  x0
+.size   good_adrp, .-good_adrp
+
+.globl  good_adrp_add
+.type   good_adrp_add,@function
+good_adrp_add:
+// CHECK-NOT: good_adrp_add
+adrpx0, sym
+add x0, x0, :lo12:sym
+br  x0
+.size   good_adrp_add, .-good_adrp_add
+
+.globl  good_adrp_add_with_const_offset
+.type   good_adrp_add_with_const_offset,@function
+good_adrp_add_with_const_offset:
+// CHECK-NOT: good_adrp_add_with_const_offset
+adrpx0, sym
+add x0, x0, :lo12:sym
+add x0, x0, #8
+br  x0
+.size   good_adrp_add_with_const_offset, 
.-good_adrp_add_with_const_offset
+
+.globl  bad_adrp_with_nonconst_offset
+.type   bad_adrp_with_nonconst_offset,@function
+bad_adrp_with_nonconst_offset:
+// CHECK-LABEL: GS-PAUTH: non-protected call found in function 
bad_adrp_with_nonconst_offset, 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]+}}:  add x0, x0, x1
+// CHECK-NEXT:  This happens in the following basic block:
+// CHECK-NEXT:  {{[0-9a-f]+}}:   adrpx0, #{{.*}}
+// CHECK-NEXT:  {{[0-9a-f]+}}:   add x0, x0, x1
+// CHECK-NEXT:  {{[0-9a-f]+}}:   br  x0 # TAILCALL
+adrpx0, sym
+add x0, x0, x1
+br  x0
+.size   bad_adrp_with_nonconst_offset, .-bad_adrp_with_nonconst_offset
+
+.globl  bad_split_adrp
+.type   bad_split_adrp,@function
+bad_split_adrp:
+// CHECK-LABEL: GS-PAUTH: non-protected call found in function bad_split_adrp, 
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]+}}:  add x0, x0, #0x{{[0-9a-f]+}}
+// CHECK-NEXT:  This happens in the following basic block:
+// CHECK-NEXT:  {{[0-9a-f]+}}:   add x0, x0, #0x{{[0-9a-f]+}}
+// CHECK-NEXT:  {{[0-9a-f]+}}:   br  x0 # UNKNOWN CONTROL FLOW
+cbz x2, 1f
+adrpx0, sym
+1:
+add x0, x0, :lo12:sym
+br  x0
+.size   bad_split_adrp, .-bad_split_adrp
+
+// Materialization of absolute addresses is not expected.
+
+.globl  bad_immediate_constant
+.type   bad_immediate_constant,@function
+bad_immediate_constant:
+// CHECK-LABEL: GS-PAUTH: non-protected call found in function 
bad_immediate_constant, 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]+}}:  mov x0, #{{.*}}
+// CHECK-NEXT:  This happens in the following basic block:
+// CHECK-NEXT:  {{[0-9a-f]+}}:   mov x0, #{{.*}}
+// CHECK-NEXT:  {{[0-9a-f]+}}:   br  x0 # TAILCALL
+movzx0, #1234
+br  x0

jacobbramley wrote:

I think the classification of good and bad sequences is probably a bit tricky 
in general. For example, the `#1234` is not attacker-controlled, and in some 
real code we _might_ use `movz` and `movk` to materialise a constant address.

We can surely update these tests as other cases come up, so I don't think this 
needs to change, but I wanted to acknowledge i

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: Detect address materialization and arithmetics (PR #132540)

2025-03-26 Thread Jacob Bramley via llvm-branch-commits


@@ -0,0 +1,228 @@
+// RUN: %clang %cflags -march=armv8.3-a %s -o %t.exe
+// RUN: llvm-bolt-binary-analysis --scanners=pauth %t.exe 2>&1 | FileCheck %s
+
+// Test various patterns that should or should not be considered safe
+// materialization of PC-relative addresses.
+//
+// Note that while "instructions that write to the affected registers"
+// section of the report is still technically correct, it does not necessarily
+// mentions the instructions that are used incorrectly.

jacobbramley wrote:

s/mentions/mention/

https://github.com/llvm/llvm-project/pull/132540
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: improve handling of unreachable basic blocks (PR #136183)

2025-05-20 Thread Jacob Bramley via llvm-branch-commits

jacobbramley wrote:

Just a thought: if BOLT has an incomplete CFG such that there are 
apparently-unreachable basic blocks, then either there's some genuine dead 
code, or some control flow that BOLT doesn't understand. If the basic block 
begins with `BTI j` (or an implicit alternative) then a computed branch is 
probably intended, and in that case, don't we have a potential problem for all 
basic blocks? That is, an attacker could divert a computed branch to _any_ `BTI 
j(c)`.

A warning is probably the right approach for now, anyway.

The code looks broadly sensible to me but I'm not sure if I'm the right person 
to do an implementation review here, so I just looked at a high level.

https://github.com/llvm/llvm-project/pull/136183
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits