| Issue |
178232
|
| Summary |
[BOLT][Gadget scanner] CFG is constructed when it should not in relocation mode
|
| Labels |
BOLT
|
| Assignees |
|
| Reporter |
atrosinenko
|
Various tests under `bolt/test/binary-analysis/AArch64/` use the same pattern to inhibit CFG reconstruction in `*_nocfg` test cases:
```asm
adr xN, 1f
br xN
1:
; ... actual test case ...
```
Adding a recommended `-Wl,--emit-relocs` option to the `RUN: %clang ...` line breaks the tests, as CFG is now formally reconstructed for these functions (but `br xN` is still annotated with an `# UNKNOWN CONTROL FLOW` comment, that is why I say "formally").
For a function to be affected, it does not necessarily have to contain relocation, but relocations have to be emitted for any function in the binary.
## How to reproduce
Compile the following source:
```asm
.text
.globl func
.type func,@function
func:
adr x1, 1f
br x1
1:
ret x0
.size func, .-func
.globl other_func
.type other_func,@function
other_func:
adr x0, sym
ret
.size other_func, .-other_func
```
without `-Wl,--emit-relocs`:
```
clang -target aarch64-linux-gnu -march=armv8.3-a -fuse-ld=lld \
-Wl,--unresolved-symbols=ignore-all -nostdlib \
nocfg-test.s -o nocfg-test
```
As expected, a report for non-protected `ret x0` is generated. Note that it does not mention `..., basic block <name>, ...` in the first line of the report:
```
$ ./bin/llvm-bolt-binary-analysis --scanners=pauth ./nocfg-test
BOLT-INFO: shared object or position-independent executable detected
BOLT-INFO: Target architecture: aarch64
BOLT-INFO: BOLT version: 3de4d32a7228519312a844bcd48a34124b1a718b
BOLT-INFO: first alloc address is 0x0
BOLT-INFO: creating new program header table at address 0x200000, offset 0x200000
BOLT-WARNING: non-relocation mode for AArch64 is not fully supported
GS-PAUTH: non-protected ret found in function func, at address 102b8
The instruction is 000102b8: ret x0 # Offset: 8
The 0 instructions that write to the affected registers after any authentication are:
```
<details>
<summary>Disassembled function dumped with `-no-threads -debug-_only_=bolt-pauth-scanner`</summary>
`func` has `State: disassembled`, `IsSimple: 0` and `BB Count: 0`.
```
Binary Function "func" {
Number : 1
State : disassembled
Address : 0x102b0
Size : 0xc
MaxSize : 0xc
Offset : 0x2b0
Section : .text
Orc Section : .local.text.func
LSDA : 0x0
IsSimple : 0
IsMultiEntry: 1
IsSplit : 0
BB Count : 0
Secondary Entry Points : __ENTRY_func@0x102b8
}
.LBB00:
00000000: adr x1, __ENTRY_func@0x102b8
00000004: br x1 # UNKNOWN CONTROL FLOW # Offset: 4
__ENTRY_func@0x102b8 (Entry Point):
.Ltmp0:
00000008: ret x0 # Offset: 8
DWARF CFI Instructions:
<empty>
End of Function "func"
# ...
Binary Function "other_func" {
Number : 2
State : CFG constructed
Address : 0x102bc
Size : 0x8
MaxSize : 0x8
Offset : 0x2bc
Section : .text
Orc Section : .local.text.other_func
LSDA : 0x0
IsSimple : 1
IsMultiEntry: 0
IsSplit : 0
BB Count : 1
Hash : 3cab5d975d7c2f39
BB Layout : .LBB01
}
.LBB01 (2 instructions, align : 1)
Entry Point
00000000: adr x0, other_func
00000004: ret
DWARF CFI Instructions:
<empty>
End of Function "other_func"
```
</details>
Then, recompile `nocfg-test` binary with `-Wl,--emit-relocs` option. The output of gadget scanner is now
```
$ ./bin/llvm-bolt-binary-analysis --scanners=pauth ./nocfg-test
BOLT-INFO: shared object or position-independent executable detected
BOLT-INFO: Target architecture: aarch64
BOLT-INFO: BOLT version: 3de4d32a7228519312a844bcd48a34124b1a718b
BOLT-INFO: first alloc address is 0x0
BOLT-INFO: creating new program header table at address 0x200000, offset 0x200000
BOLT-INFO: enabling relocation mode
GS-PAUTH: non-protected ret found in function func, basic block .Ltmp0, at address 102b8
The instruction is 000102b8: ret x0
The 0 instructions that write to the affected registers after any authentication are:
```
CFG information is formally available now, which can be seen by the basic block name being mentioned in the report.
<details>
<summary>Disassembled function dumped with `-no-threads -debug-_only_=bolt-pauth-scanner`</summary>
`func` has `State: CFG constructed`, `IsSimple: 0` and `BB Count: 2`.
```
Binary Function "func" {
Number : 1
State : CFG constructed
Address : 0x102b0
Size : 0xc
MaxSize : 0xc
Offset : 0x2b0
Section : .text
Orc Section : .local.text.func
LSDA : 0x0
IsSimple : 0
IsMultiEntry: 1
IsSplit : 0
BB Count : 2
Hash : 592111a3fb9ca883
Secondary Entry Points : __ENTRY_func@0x102b8
BB Layout : .LBB00, .Ltmp0
}
.LBB00 (2 instructions, align : 1)
Entry Point
00000000: adr x1, __ENTRY_func@0x102b8
00000004: br x1 # UNKNOWN CONTROL FLOW
.Ltmp0 (1 instructions, align : 1)
Secondary Entry Point: __ENTRY_func@0x102b8
00000008: ret x0
DWARF CFI Instructions:
<empty>
End of Function "func"
# ...
Binary Function "other_func" {
Number : 2
State : CFG constructed
Address : 0x102bc
Size : 0x8
MaxSize : 0x8
Offset : 0x2bc
Section : .text
Orc Section : .local.text.other_func
LSDA : 0x0
IsSimple : 1
IsMultiEntry: 0
IsSplit : 0
BB Count : 1
Hash : 3cab5d975d7c2f39
BB Layout : .LBB01
}
.LBB01 (2 instructions, align : 1)
Entry Point
00000000: adr x0, other_func
00000004: ret
DWARF CFI Instructions:
<empty>
End of Function "other_func"
```
</details>
Removing `other_func` eliminates the only emitted relocation from `nocfg-test` binary, resulting in restoring the original behavior of treating `func` as not having a valid CFG (whether `-Wl,--emit-relocs` is passed or not).
<details>
<summary>Disassembled function dumped with `-no-threads -debug-_only_=bolt-pauth-scanner`</summary>
```
Binary Function "func" {
Number : 1
State : disassembled
Address : 0x102b0
Size : 0xc
MaxSize : 0xc
Offset : 0x2b0
Section : .text
Orc Section : .local.text.func
LSDA : 0x0
IsSimple : 0
IsMultiEntry: 1
IsSplit : 0
BB Count : 0
Secondary Entry Points : __ENTRY_func@0x102b8
}
.LBB00:
00000000: adr x1, __ENTRY_func@0x102b8
00000004: br x1 # UNKNOWN CONTROL FLOW # Offset: 4
__ENTRY_func@0x102b8 (Entry Point):
.Ltmp0:
00000008: ret x0 # Offset: 8
DWARF CFI Instructions:
<empty>
End of Function "func"
```
</details>
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs