CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
261 lines
9.9 KiB
ArmAsm
261 lines
9.9 KiB
ArmAsm
// -Wl,--no-relax prevents converting ADRP+ADD pairs into NOP+ADR.
|
|
// RUN: %clang %cflags -march=armv8.3-a -Wl,--no-relax %s -o %t.exe
|
|
// RUN: llvm-bolt-binary-analysis --scanners=ptrauth-all %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
|
|
// mention the instructions that are used incorrectly.
|
|
|
|
.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
|
|
paciza x0
|
|
ret
|
|
.size good_adr, .-good_adr
|
|
|
|
.globl good_adrp
|
|
.type good_adrp,@function
|
|
good_adrp:
|
|
// CHECK-NOT: good_adrp
|
|
adrp x0, sym
|
|
paciza x0
|
|
ret
|
|
.size good_adrp, .-good_adrp
|
|
|
|
.globl good_adrp_add
|
|
.type good_adrp_add,@function
|
|
good_adrp_add:
|
|
// CHECK-NOT: good_adrp_add
|
|
adrp x0, sym
|
|
add x0, x0, :lo12:sym
|
|
paciza x0
|
|
ret
|
|
.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
|
|
adrp x0, sym
|
|
add x0, x0, :lo12:sym
|
|
add x0, x0, #8
|
|
paciza x0
|
|
ret
|
|
.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: signing oracle found in function bad_adrp_with_nonconst_offset, basic block {{[^,]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x0
|
|
// 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]+}}: adrp x0, #{{.*}}
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, x1
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: paciza x0
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
adrp x0, sym
|
|
add x0, x0, x1
|
|
paciza x0
|
|
ret
|
|
.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: signing oracle found in function bad_split_adrp, basic block {{[^,]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x0
|
|
// 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]+}}: paciza x0
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
cbz x2, 1f
|
|
adrp x0, sym
|
|
1:
|
|
add x0, x0, :lo12:sym
|
|
paciza x0
|
|
ret
|
|
.size bad_split_adrp, .-bad_split_adrp
|
|
|
|
// Materialization of absolute addresses is not handled, as it is not expected
|
|
// to be used by real-world code, but can be supported if needed.
|
|
|
|
.globl bad_immediate_constant
|
|
.type bad_immediate_constant,@function
|
|
bad_immediate_constant:
|
|
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_immediate_constant, basic block {{[^,]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x0
|
|
// 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]+}}: paciza x0
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
movz x0, #1234
|
|
paciza x0
|
|
ret
|
|
.size bad_immediate_constant, .-bad_immediate_constant
|
|
|
|
// Any ADR or ADRP instruction followed by any number of increments/decrements
|
|
// by constant is considered safe.
|
|
|
|
.globl good_adr_with_add
|
|
.type good_adr_with_add,@function
|
|
good_adr_with_add:
|
|
// CHECK-NOT: good_adr_with_add
|
|
adr x0, sym
|
|
add x0, x0, :lo12:sym
|
|
paciza x0
|
|
ret
|
|
.size good_adr_with_add, .-good_adr_with_add
|
|
|
|
.globl good_adrp_with_add_non_consecutive
|
|
.type good_adrp_with_add_non_consecutive,@function
|
|
good_adrp_with_add_non_consecutive:
|
|
// CHECK-NOT: good_adrp_with_add_non_consecutive
|
|
adrp x0, sym
|
|
mul x1, x2, x3
|
|
add x0, x0, :lo12:sym
|
|
paciza x0
|
|
ret
|
|
.size good_adrp_with_add_non_consecutive, .-good_adrp_with_add_non_consecutive
|
|
|
|
.globl good_many_offsets
|
|
.type good_many_offsets,@function
|
|
good_many_offsets:
|
|
// CHECK-NOT: good_many_offsets
|
|
adrp x0, sym
|
|
add x1, x0, #8
|
|
add x2, x1, :lo12:sym
|
|
paciza x2
|
|
ret
|
|
.size good_many_offsets, .-good_many_offsets
|
|
|
|
.globl good_negative_offset
|
|
.type good_negative_offset,@function
|
|
good_negative_offset:
|
|
// CHECK-NOT: good_negative_offset
|
|
adr x0, sym
|
|
sub x1, x0, #8
|
|
paciza x1
|
|
ret
|
|
.size good_negative_offset, .-good_negative_offset
|
|
|
|
// MOV Xd, Xm (which is an alias of ORR Xd, XZR, Xm) is handled as part of
|
|
// support for address arithmetics, but ORR in general is not.
|
|
// This restriction may be relaxed in the future.
|
|
|
|
.globl good_mov_reg
|
|
.type good_mov_reg,@function
|
|
good_mov_reg:
|
|
// CHECK-NOT: good_mov_reg
|
|
adrp x0, sym
|
|
mov x1, x0
|
|
orr x2, xzr, x1 // the same as "mov x2, x1"
|
|
paciza x2
|
|
ret
|
|
.size good_mov_reg, .-good_mov_reg
|
|
|
|
.globl bad_orr_not_xzr
|
|
.type bad_orr_not_xzr,@function
|
|
bad_orr_not_xzr:
|
|
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_orr_not_xzr, basic block {{[^,]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x2
|
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: orr x2, x1, x0
|
|
// CHECK-NEXT: This happens in the following basic block:
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: adrp x0, #{{(0x)?[0-9a-f]+}}
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: mov x1, #0
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: orr x2, x1, x0
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: paciza x2
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
adrp x0, sym
|
|
// The generic case of "orr Xd, Xn, Xm" is not allowed so far,
|
|
// even if Xn is known to be safe
|
|
movz x1, #0
|
|
orr x2, x1, x0
|
|
paciza x2
|
|
ret
|
|
.size bad_orr_not_xzr, .-bad_orr_not_xzr
|
|
|
|
.globl bad_orr_not_lsl0
|
|
.type bad_orr_not_lsl0,@function
|
|
bad_orr_not_lsl0:
|
|
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_orr_not_lsl0, basic block {{[^,]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x2
|
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: orr x2, xzr, x0, lsl #1
|
|
// CHECK-NEXT: This happens in the following basic block:
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: adrp x0, #{{(0x)?[0-9a-f]+}}
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: orr x2, xzr, x0, lsl #1
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: paciza x2
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
adrp x0, sym
|
|
// Currently, the only allowed form of "orr" is that used by "mov Xd, Xn" alias.
|
|
// This can be relaxed in the future.
|
|
orr x2, xzr, x0, lsl #1
|
|
paciza x2
|
|
ret
|
|
.size bad_orr_not_lsl0, .-bad_orr_not_lsl0
|
|
|
|
// Check that the input register operands of `add`/`mov` is correct.
|
|
|
|
.globl bad_add_input_reg
|
|
.type bad_add_input_reg,@function
|
|
bad_add_input_reg:
|
|
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_add_input_reg, basic block {{[^,]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x0
|
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: add x0, x1, #0x{{[0-9a-f]+}}
|
|
// CHECK-NEXT: This happens in the following basic block:
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: adrp x0, #{{(0x)?[0-9a-f]+}}
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: add x0, x1, #0x{{[0-9a-f]+}}
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: paciza x0
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
adrp x0, sym
|
|
add x0, x1, :lo12:sym
|
|
paciza x0
|
|
ret
|
|
.size bad_add_input_reg, .-bad_add_input_reg
|
|
|
|
.globl bad_mov_input_reg
|
|
.type bad_mov_input_reg,@function
|
|
bad_mov_input_reg:
|
|
// CHECK-LABEL: GS-PAUTH: signing oracle found in function bad_mov_input_reg, basic block {{[^,]+}}, at address
|
|
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: paciza x0
|
|
// CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are:
|
|
// CHECK-NEXT: 1. {{[0-9a-f]+}}: mov x0, x1
|
|
// CHECK-NEXT: This happens in the following basic block:
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: adrp x0, #{{(0x)?[0-9a-f]+}}
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: mov x0, x1
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: paciza x0
|
|
// CHECK-NEXT: {{[0-9a-f]+}}: ret
|
|
adrp x0, sym
|
|
mov x0, x1
|
|
paciza x0
|
|
ret
|
|
.size bad_mov_input_reg, .-bad_mov_input_reg
|
|
|
|
.globl main
|
|
.type main,@function
|
|
main:
|
|
mov x0, 0
|
|
ret
|
|
.size main, .-main
|