https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128281
Bug ID: 128281
Summary: gimple-fold and omp-expand fold atomic
compare-exchange to IFN_ATOMIC_COMPARE_EXCHANGE before
HWASan/ASan/TSan
Product: gcc
Version: 16.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: sanitizer
Assignee: unassigned at gcc dot gnu.org
Reporter: 220245569 at seu dot edu.cn
CC: 220255623 at seu dot edu.cn, dodji at gcc dot gnu.org,
dvyukov at gcc dot gnu.org, jakub at gcc dot gnu.org,
jianhao.xu at seu dot edu.cn, kcc at gcc dot gnu.org
Target Milestone: ---
Target: *-*-*
Summary
-------
When `BUILT_IN_ATOMIC_COMPARE_EXCHANGE_N` is folded into the internal function
`IFN_ATOMIC_COMPARE_EXCHANGE`, `pass_asan` (ASan/HWASan) and `pass_tsan` do not
instrument `IFN_ATOMIC_COMPARE_EXCHANGE`. Two early folding paths fail to gate
on active sanitizers:
1. `optimize_atomic_compare_exchange_p` (`gcc/gimple-fold.cc:5587-5597`) checks
`!(flag_sanitize & (SANITIZE_THREAD | SANITIZE_ADDRESS))`, omitting
`SANITIZE_HWADDRESS`. At `-O1` and above under `-fsanitize=hwaddress`, every
C/C++ `atomic_compare_exchange_*` call is folded to
`IFN_ATOMIC_COMPARE_EXCHANGE`
during `ccp1` (before `pass_asan`) and emits zero `__hwasan_store*` tag
checks!
2. `expand_omp_atomic_cas` (`gcc/omp-expand.cc:9248-9258`) unconditionally
emits
`IFN_ATOMIC_COMPARE_EXCHANGE` for `#pragma omp atomic compare` without
checking any sanitizer flag, bypassing ASan, HWASan, and TSan.
Reproducer
----------
$ cat trigger.c
#include <stdatomic.h>
#include <stdbool.h>
bool hwasan_atomic_cas(_Atomic int *ptr, int expected, int desired) {
return atomic_compare_exchange_strong(ptr, &expected, desired);
}
int hwasan_atomic_load(_Atomic int *ptr) {
return atomic_load(ptr);
}
Compile flag: aarch64-linux-gnu-gcc -O2 -fsanitize=hwaddress -S trigger.c
$ cat trigger.s
hwasan_atomic_cas:
stp x29, x30, [sp, -32]!
...
bl __aarch64_cas4_acq_rel # ZERO __hwasan_store4 tag check!
cmp w0, w19
...
ret
hwasan_atomic_load:
stp x29, x30, [sp, -32]!
mov x29, sp
str x0, [sp, 24]
bl __hwasan_load4 # atomic_load is properly checked
ldr x0, [sp, 24]
ldar w0, [x0]
ldp x29, x30, [sp], 32
ret
Suggested Fix
-------------
1. Add `SANITIZE_HWADDRESS` to the exclusion mask in
`optimize_atomic_compare_exchange_p` (`gcc/gimple-fold.cc:5592`).
2. Gate `IFN_ATOMIC_COMPARE_EXCHANGE` emission in `expand_omp_atomic_cas`
(`gcc/omp-expand.cc:9248`) on `!(flag_sanitize & (SANITIZE_ADDRESS |
SANITIZE_HWADDRESS | SANITIZE_THREAD))`.