https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128280

            Bug ID: 128280
           Summary: ipa-inline: sanitize_attrs_match_for_inline_p omits
                    SANITIZE_HWADDRESS, SANITIZE_MEMTAG_STACK, and
                    SANITIZE_SHADOW_CALL_STACK
           Product: gcc
           Version: 16.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: ipa
          Assignee: unassigned at gcc dot gnu.org
          Reporter: 220245569 at seu dot edu.cn
                CC: 220255623 at seu dot edu.cn, jianhao.xu at seu dot edu.cn
  Target Milestone: ---
            Target: aarch64-*-*, x86_64-*-*

Summary
-------
In `gcc/ipa-inline.cc:321-329`, `sanitize_attrs_match_for_inline_p` checks only
`SANITIZE_ADDRESS | SANITIZE_THREAD | SANITIZE_UNDEFINED |
SANITIZE_UNDEFINED_NONDEFAULT |
SANITIZE_POINTER_COMPARE | SANITIZE_POINTER_SUBTRACT`, omitting
`SANITIZE_HWADDRESS`, `SANITIZE_MEMTAG_STACK`, and
`SANITIZE_SHADOW_CALL_STACK`.

Because `can_inline_edge_p` and `can_early_inline_edge_p` rely on this mask for
non-`always_inline` functions:
1. A HWASan-instrumented static helper is silently inlined into a
   `__attribute__((no_sanitize("hwaddress")))` caller, stripping all
   `__hwasan_load*`/`__hwasan_store*` checks from the inlined body.
2. Conversely, a `__attribute__((no_sanitize("hwaddress")))` low-level helper
   that dereferences untagged pointers is silently inlined into a sanitized
   caller, where `pass_asan` instruments its raw pointer dereference with
   `__hwasan_load*` and causes a deterministic runtime tag-mismatch crash.

Reproducer
----------
$ cat trigger.c
static int sanitized_callee(int *buf, int idx) {
    return buf[idx];
}

__attribute__((no_sanitize("hwaddress")))
int unsanitized_caller(int *buf, int idx) {
    return sanitized_callee(buf, idx);
}

__attribute__((no_sanitize("hwaddress")))
static int raw_untagged_read(int *raw_ptr) {
    return *raw_ptr;
}

int sanitized_caller(int *raw_ptr) {
    return raw_untagged_read(raw_ptr);
}

Compile flag: aarch64-linux-gnu-gcc -O2 -fsanitize=hwaddress -S trigger.c

$ cat trigger.s
unsanitized_caller:
        ldr     w0, [x0, w1, sxtw 2]    # sanitized_callee inlined;
__hwasan_load4 stripped!
        ret

sanitized_caller:
        stp     x29, x30, [sp, -32]!
        mov     x29, sp
        str     x0, [sp, 24]
        bl      __hwasan_load4          # no_sanitize helper inlined and
falsely instrumented!
        ldr     x0, [sp, 24]
        ldr     w0, [x0]
        ldp     x29, x30, [sp], 32
        ret

Suggested Fix
-------------
Add `SANITIZE_HWADDRESS | SANITIZE_MEMTAG_STACK | SANITIZE_SHADOW_CALL_STACK`
to
the mask in `sanitize_attrs_match_for_inline_p` (`gcc/ipa-inline.cc:321-329`).

Reply via email to