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))`.

Reply via email to