https://sourceware.org/bugzilla/show_bug.cgi?id=34962
Bug ID: 34962
Summary: AArch64 gold --icf=safe folds functions addressed by
R_AARCH64_ABS64
Product: binutils
Version: 2.48 (HEAD)
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: ld
Assignee: unassigned at sourceware dot org
Reporter: basavesh.shivakumar at wsu dot edu
Target Milestone: ---
Created attachment 17255
--> https://sourceware.org/bugzilla/attachment.cgi?id=17255&action=edit
repro
## Description
AArch64 gold does not treat `R_AARCH64_ABS64` as a possible function-pointer
relocation for safe identical code folding. Consequently, `--icf=safe` folds
two byte-identical functions whose addresses are stored in a data table. Their
addresses then compare equal at run time even though the program takes both
addresses and relies on their distinct identities.
The attached object contains:
```asm
token_table:
.xword twin_a
.xword twin_b
```
These entries have `R_AARCH64_ABS64` relocations. With current AArch64 gold
and `--icf=safe`, both symbols resolve to `0x40014c`. With the same gold build
and `--icf=none`, they resolve to `0x40014c` and `0x400154`. LLD and mold also
keep the pair distinct under their safe-ICF modes when given the same three
objects.
The source-level omission is in `possible_function_pointer_reloc` in
`gold/aarch64.cc`. It returns true for the ADRP/ADD and GOT relocation forms,
but its switch does not include `R_AARCH64_ABS64`. The AArch64
`local_reloc_may_be_function_pointer` and
`global_reloc_may_be_function_pointer` paths use that function to decide
whether safe ICF may fold the referenced function.
GNU gold from Binutils 2.44 reproduced the result. I also fetched and built
official Binutils master commit
`f735688fcb997db4821ed6f9df40425b31b0cd0c` (GNU gold
2.47.50.20261105) with all targets enabled. Its `ld-new` had SHA-256
`e6d6f84c072dbf9357d55407dfc8577f6a078d81308048c6802d31cb144e9dd4`
and still folded the pair under `--icf=safe`.
The reproducer includes a bounded constant-time composition. A dispatch
fixture compares the two stored function addresses. Distinct addresses select
a wrapper with a fixed-address table load; equal addresses select a wrapper
whose branch and table address depend on one input bit. Both wrappers then
call the same separately compiled HACL* Curve25519 implementation. The gold
safe-ICF output selects the latter wrapper, while gold `--icf=none`, LLD, and
mold select the fixed-address wrapper. Both inputs exit with status 42 and
emit the same 32-byte result, with SHA-256
`233ced774423c7a7f91254bd2346d889e2ccab33cb6c98947844f1ef6c4f493f`.
The provider policy is a diagnostic fixture. This does not claim that HACL*
uses function addresses this way or that HACL* is at fault. It demonstrates
that an unexpected safe-ICF fold can change a program's selected
implementation and introduce input-dependent architectural behavior; it does
not claim measured cache timing or key recovery.
Reproduction:
```sh
tar -xzf gold-aarch64-safe-icf-ct-provider-switch-bugzilla.tar.gz
cd artifact
GOLD=/path/to/gold/ld-new ./repro.sh
```
The script requires `qemu-aarch64`, `nm`, `sha256sum`, and a POSIX shell. If
`GOLD` is unset, it uses `aarch64-linux-gnu-ld.gold`. Installed LLD and mold
are run as controls. The script verifies the frozen inputs, freshly links each
output, checks the symbol identities, executes both input values, and verifies
equal results. It finishes with:
```text
PASS: AArch64 gold safe ICF folds the address-taken pair
```
--
You are receiving this mail because:
You are on the CC list for the bug.