<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/154140>154140</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [scudo] Crash from top-byte tagging when PR_TAGGED_ADDR_ENABLE not set
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          KonradHohentanner
      </td>
    </tr>
</table>

<pre>
    **Summary**
On AArch64 systems with hardware MTE support present (HWCAP2_MTE) but where the dynamic loader does not automatically enable tagged addresses/MTE for the process (e.g., ld-linux-aarch64 in glibc), Scudo currently assumes it is running in an MTE-enabled environment.
This results in Scudo inserting non-zero top-byte tags (via addFixedTag) even when PR_TAGGED_ADDR_ENABLE and MTE faulting are not enabled, causing errors.

Android is unaffected because its dynamic loader explicitly enables tagged addresses/MTE via prctl(PR_SET_TAGGED_ADDR_CTRL, …).

**Environment**
Hardware: AArch64 with MTE
Kernel: recent Linux
libc/loader: glibc (no MTE enablement by default)
Scudo built with memory tagging support

**What happens**
Hardware advertises MTE via AT_HWCAP2 & HWCAP2_MTE.
The process does not have tagged addresses/MTE activated, no previous prctl(PR_SET_TAGGED_ADDR_CTRL, ...).
Scudo still adds non-zero tags to pointer top bytes in software (addFixedTag).
Those tagged pointers are reported as corrupted chunk header and cause a segmentation fault.

**Expected behavior**
Scudo should only insert top-byte tags when MTE/tagged addresses are actually enabled for the current process (i.e., after the loader/libc has called PR_SET_TAGGED_ADDR_CTRL).

**Fix**
On Linux systems, function systemSupportsMemoryTagging should additionally check whether TBI and/or MTE has been enabled for the current process.
We can prepare a pull request with this change if that would be helpful.

**Minimal reproduction (Ubuntu 22.04 Docker container running binary in QEMU)**
_Dockerfile_
```
FROM ubuntu:24.04
 
RUN apt-get update && apt-get install -y clang libc6-dev-arm64-cross libstdc++-11-dev-arm64-cross binutils-aarch64-linux-gnu qemu-user-static git lld
RUN mkdir /src && cat <<'EOF' > /src/test.c
#include <stdlib.h>
int main() {
    void *ptr = malloc(56);
    free(ptr); // Error does not appear without call to free
    return 42;
}
EOF
RUN mkdir /output
RUN clang -fuse-ld=lld -target gnu-linux-aarch64 -o /output/test  /src/test.c
RUN git clone --depth 1 --filter=tree:0 -n https://github.com/llvm/llvm-project.git /src/llvm-project
RUN cd /src/llvm-project && git sparse-checkout set compiler-rt/lib/scudo/standalone && git checkout
RUN clang++ -fuse-ld=lld -target gnu-linux-aarch64 -fPIC -g -std=c++17 -O2 -pthread -shared \
  -I /src/llvm-project/compiler-rt/lib/scudo/standalone/include \
  /src/llvm-project/compiler-rt/lib/scudo/standalone/*.cpp \
  -o /output/libscudo.so
ENTRYPOINT ["qemu-aarch64-static", "-L", "/usr/aarch64-linux-gnu", "-E", "LD_PRELOAD=/output/libscudo.so", "/output/test"]
```

_Setup + Run Commands_
```
docker build . -t reproduce
docker run reproduce
```
leads to: _Scudo ERROR: corrupted chunk header at address 0x200402500ed2790: most likely due to memory corruption_
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJykV11vIjsS_TXmpdSoMd8PPHQC3BndZJJlGI32CZl2QXvHbff1BxP216_K3RCSudm9VytFCvijXOfUqWMjvFdHg7hg4zs2XvZEDJV1i9-tcUJ-shWaIIxB19tbeV4wXjBefI11Ldy5_cLy4slAUbiymozAn33A2sNPFSqohJM_hUN43K7Ax6axLkDj0KMJwPjs0_f74pnvHrcrxuewjwF-VugQQoUgz0bUqgRthUQH0qIHYwOIGGwtgiqF1mdAI_YaIYjjESUIKR16j57xNR15sC7Fapwt0Xs6EvvHPuP3oGWmlYkvmRBt4srAUat9yfic5r-WUVooo3Nogj6D8D7W6EEFUB5cNEaZI20ShtBlbSIS0JyUs6ZGE_osL7YVrUYfdfC0ug2rjEcXKICxJvs3OgvBNtn-HBKUlOhJCcKzVi8ot-JIBOEJDTFk4Hmz2xa__bZa7orlcrNbfSnuHlYgjExMH0TUKTpRT5x1yRGuUkRPU-icdZ5SZHlRGOmskoQsGnE4YBlQwh5pMYIK_n018KXRqlThWgH_UQkIRuPKoBmfPW92X1fbN5nfbzcPlBZbcTbLWTFhfN4l1apr9crnVW6fOlmxYXHVXdIbCSkvfkdnUNOkw5KU9kCFZnnRlnfdYqD5VHAi29hEXIuFzoL9GSQmIkkQedEWbh-VDu1ZNdbWnRNs4rNT923q3ysRoBJNg8b_kjsIeSINePRw4anY7tqOAMYn8NocrZBeZXzthUqcPtS-KIM6idBW3Vhqu5Oy0f-VavT7_a4OLWwflNZ0gr8RLOk0WGisMgEdCRhIwEnm3h5CQsn47K2IWyzWX_Pu9vskVodEIqHxUFrnYkNfyiqaH1Bhkh6JvNWlAI9HKpYIyppW9W-189JclFyJk7LuWoUOVmWjlmCNPnct-a4NU68ld1q_ZzmlK8oQb2xIXg2n841b41F9TMYjDomtCrteIkGSCiuCLDRF-bAyb1tjrV5uHTip_OK_dNIhmjIx0459bRXqH5NwtxfdthwIKRWtTWjKCssfBD5U6GB795lIZ3xtXZIqZbpHNP8LNSX7HaEUhsTXJMKgiVqDwz8i-q6RAllkWQlzRFAHCNQ1P1NSe4QKdXOI-g3uR2VULShK46yMLUbGZ9_20YQInPfzESxt-QMdlNYEoQy6q2XvlRGO6g3_WD1-S27fcbhr9xyUxh0dNsm7v7xYb54eIab4bFjwUT8fsbwAlhebb19ANCE7YoDYSBFI8xPq38uoMj4IrSE7Q6mFOQKVe5JJPGXC1ZNRVjrrPY36IEvG7xi_ywaDXxbslYlBaX-5sbr762gi_IF1zKJHl3lqhhKOKoDWssuv_iGVA8bX3pWX7EoRgA3v6Y9PV09rxqfAhqtuFQkefeiXifShMqWOEmmDD1Krfb9iQ7JaZQLUQhnGZ3RBsekd0QIAJ7pOGC-a4IANl1ALrW3J-GxMDs-Gl3UHh8j4rAmuHabzGV_Diq6nm0u_aVC4pBcbQ-oT8p60uw3kMERnYMTb2Gy6ZHlBuN5RYGNoYuhG23pkh-gx05INl1pLyIJwVLejie-eCJm9idAyBH9CGEWmApTaGoQsk9iECgaQZQelA908y0CJD4scMgNVCI1nw6JFflShivt-aWsyBn26_MsaZ_-FZehT5OuZtzMXTPLPpy-Fp_2-Ec5jlvqc-PQYoLR1ozS6zIXWkigK2ST9D8JIkeDcRLlsvyWzle_foPTw_PkesiNkPtDqTv-DKWRPHLImVA6FhMxXwqEENr5P9c4-f8ABX_81HIyvr6LuYv7fARkv-mXTvCb5Vi7U4LSt7y1J88t288_np89ftkAPb85TD19au21jxnl6G3GePbx-ZnwdPV0bv_jAzfrV6-eH5e55s3p4KpZsuPwoodvobwROQ-PlOzsks_yKITZAxd5EA_e2roWR_r1xytaG6d0koQ9ZuLo2vs66aN4M3wbQKCS9M-i5tmuv7dVm87Sh7x-9EMLlmob8hef5KOfjPEfJp_OcttXWB9DqB-ozyIhkJN1jrguorNn15GIo58O56OFiMB2Px0PO-bxXLcZ5PpgM5ge-H07mXMp8MjuMZmIw2YtJOZvOe2rB6cDZYDYYj3M-73OcjQbTaTlBLuRgOmCjHGuhdJ-E1rfu2FPeR1wMxqPBKO9psUftF60qDP6ENNvWoecWSZ37ePRslGvlg38NE1TQ6XdcK8_xEu6d8BUcnK3fvGzSzf9ffkiQ5XoMvej04u_ZE_UVpUuv0A7PacH_EwAA__8VoK9N">