# Technical Documentation: google/sanitizers

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/google/sanitizers)

### Overview (`README.md`)

# sanitizers (Archived)

**This _repository_ has been archived and is no longer actively maintained.**

The Sanitizers _repository_, which includes AddressSanitizer, MemorySanitizer, ThreadSanitizer, LeakSanitizer, and more, is now archived. The core code for these sanitizers resides within the [LLVM](http://llvm.org) repository. This repository will be retained for archival purposes, providing access to historical documentation, bugfixes, and helper code.

**Important:** Please do not file new bug reports in this repository.

**Where to Report Bugs:**

* **LLVM:** For bugs related to the sanitizer runtimes and instrumentation, please report them to the [LLVM Bug Tracker](https://github.com/llvm/llvm-project/issues/).
* **GCC:** For bugs related to the GCC port of the sanitizers, please report them to the [GCC Bugzilla](https://gcc.gnu.org/bugzilla/).
* **Linux Kernel:** For bugs related to Kernel AddressSanitizer (KASAN), Kernel MemorySanitizer (KMSAN), or Kernel ConcurrencySanitizer (KCSAN), please report them through the appropriate Linux kernel bug reporting channels, such as the [Linux kernel mailing list](https://vger.kernel.org/vger-lists.html#linux-kernel).
* **Linux Distributions:** For bugs related to compiler issues in specific Linux distributions that are not reproducible in trunk compilers, please report them to the respective distribution's bug tracker (e.g., Debian Bug Tracking System, Red Hat Bugzilla).
* **Apple and Microsoft:** For bugs related to the compilers provided by Apple (Xcode) or Microsoft (Visual Studio), please report them through the respective vendor's bug reporting channels.
* **Android NDK:** For bugs related to Android, please report them to the [NDK issue tracker](https://github.com/android/ndk).

**Documentation (Archived):**

* [AddressSanitizer](../../wiki/AddressSanitizer) (detects addressability issues) and [LeakSanitizer](../../wiki/AddressSanitizerLeakSanitizer) (detects memory leaks)
* ThreadSanitizer (detects data races and deadlocks) for [C++](../../wiki/ThreadSanitizerCppManual) and [Go](../../wiki/ThreadSanitizerGoManual)
* [MemorySanitizer](../../wiki/MemorySanitizer) (detects use of uninitialized memory)
* [HWASAN](https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html), or Hardware-assisted AddressSanitizer, a newer variant of AddressSanitizer that consumes much less memory
* [UBSan](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html), or UndefinedBehaviorSanitizer

**Kernel Sanitizers (Archived Documentation):**

* [KASAN](https://www.kernel.org/doc/html/v4.12/dev-tools/kasan.html)
* [KMSAN](https://github.com/google/kmsan)
* [KCSAN](https://github.com/google/kernel-sanitizers/blob/master/KCSAN.md)

Thank you for your understanding.

---

### Overview (`dashboard/README.md`)

# Sanitizer Dashboard

The dashboard is automatically built and updated from `master` on the GCE instance via [`start_script.sh`](start_script.sh).

## Local testing

```bash
go build -o /tmp/sanitizers . && /tmp/sanitizers > /tmp/sanitizers.html && xdg-open /tmp/sanitizers.html
```

## Creating the GCE instance

```bash
gcloud compute instances create dashboard-v3 \
  --project="sanitizer-bots" \
  --zone="us-east1-d" \
  --machine-type="e2-micro" \
  --network-tier="STANDARD" \
  --address="35.207.33.19" \
  --tags="http-server,https-server" \
  --no-service-account \
  --no-scopes \
  --shielded-secure-boot \
  --shielded-vtpm \
  --shielded-integrity-monitoring \
  --image-family="debian-13" \
  --image-project="debian-cloud" \
  --boot-disk-size="10GB" \
  --metadata=startup-script='#! /bin/bash
# for logs: sudo journalctl -u google-startup-scripts.service
set -x
which curl || (apt-get update && apt-get install -y curl)
while true; do
  curl -fL https://raw.githubusercontent.com/google/sanitizers/master/dashboard/start_script.sh | bash
  sleep 600
done'
```

---

### Overview (`mte-dynamic-carveout/README.md`)

# MTE dynamic carveout resources

This page is a collection of resources for the MTE dynamic carveout
proposal.

* [Hardware requirements and operating system design sketch](./spec.md)
* [Prototype Linux kernel patch](https://github.com/pcc/linux/tree/mte-dynamic)
* [Prototype QEMU patch](https://github.com/pcc/qemu/tree/mte-dynamic)

## Usage

The patched QEMU may be instructed to expose the tag storage to
the guest, together with the device tree nodes expected by the
patched kernel, by passing the flag `mte-shared-alloc=on` as part
of the `-machine` command line argument. For example: `-machine
virt,virtualization=on,mte=on,mte-shared-alloc=on`.

Alternatively, when using a custom device tree, specific `memory`
and `reserved-memory` device tree nodes may be used to activate the
feature.

* The `arm,mte-alloc` attribute on a `memory` node indicates that any tag
  storage for that memory is described by `reserved-memory` nodes with the
  `compatible = "arm,mte-tag-storage"` attribute.

* The `arm,no-mte` attribute on a `memory` node indicates that the
  memory region is not capable of being mapped with the Tagged Normal
  attribute. At present this attribute may only be used if the memory
  region is fully covered by `reserved-memory` nodes with `compatible =
  "arm,mte-tag-storage"`.

* The `storage-base` attribute on a `reserved-memory` node with
  `compatible = "arm,mte-tag-storage"` specifies the physical address of
  the start of the MTE-capable memory region whose tag storage is described
  by the `reserved-memory` node.

## Limitations

* This implementation is not compatible with HW tag-based KASAN, nor
  with KVM with MTE-enabled VMs. If you try to use either of these features,
  you will probably crash the kernel.

* This implementation has some as-yet-undebugged issues which can cause
  kernel warnings about invalid page flags during certain memory-intensive
  operations.

* Automatic migration of pages between the tagged and untagged freelists
  is not yet implemented.

---

### Overview (`android/app/README.md`)

# Sanitizer Example Android Apps

This repository contains an example Android app that is built with the following
memory safety tools:

 1. [HWASan](https://developer.android.com/ndk/guides/hwasan),
 2. [GWP-ASan](https://developer.android.com/ndk/guides/gwp-asan),
 3. [MTE](https://security.googleblog.com/2019/08/adopting-arm-memory-tagging-extension.html)
    (in both SYNChronous and ASYNChronous modes), or
 4. None of the above.

Installing the Prebuilt Apps
---

Prebuilt apps can be found in the `prebuilt-apks` folder. They can be installed
onto your device by `adb install prebuilt-apks/app-<variant>-release.apk`.

Note: If you see errors along the lines of: `Failure
[INSTALL_FAILED_VERIFICATION_FAILURE: Package Verification Result]`, you may
need to `adb unroot` first. Once installed, the app will be visible in your app
drawer under the name "Sanitizer Test App".

Uninstalling the App
---

You can remove the app on-device by long pressing the app in the app drawer, and
dragging it to the top right of the screen, into the "Uninstall" bin.

Building the App Yourself
---

To build the app yourself, simply `cd src && ./gradlew build`. For each
sanitizer, this will build a debug version of the app and place it under
`app/build/outputs/apk/gwpAsan/release/app-<variant>-debug-unsigned.apk`.
Installation instructions are the same as the prebuilts.

If your device policy doesn't allow for unsigned apps to be installed, you can
either use the prebuilt apps - or use the `build-and-sign.sh` script to build
and sign your own app. You will likely need to create your own signing
certificate, instructions are available in the script. Once the script runs,
signed APKs are available in `src/apks`.

---

### Overview (`hwaddress-sanitizer/check_registers/README.md`)

# check_registers - tests for x86 address tagging support in various registers

## Overview

`check_registers` is a test suite that evaluates the capabilities of a x86 CPU
with hardware pointer tagging support (e.g. Intel LAM or AMD UAI). It consists
of a number of assembly functions that check the behavior of different
instructions in the presence of tagged pointers.

`check_registers` is meant to be run on a x86 host that has a CPU with hardware
pointer tagging support (e.g. Intel LAM or AMD UAI) and a kernel with the
pointer tagging API:
 - `arch_prctl(ARCH_GET_MAX_TAG_BITS, &tag_bits)`
 - `arch_prctl(ARCH_ENABLE_TAGGED_ADDR, tag_bits)`
 - `arch_prctl(ARCH_GET_UNTAG_MASK, &tag_mask)`

As of March 2023, this API exists as a set of downstream kernel patches
available at
https://lore.kernel.org/lkml/20230123220500.21077-1-kirill.shutemov@linux.intel.com/

## Building

```
  $ g++ check_registers.cc -o check_registers
```

## Running

```
  $ ./check_registers [notag] [expect] [list of testcases]
```

By default, `./check_registers` runs all tests, passing tagged pointers to them
and printing the results to stdout. If the host does not support pointer
tagging, all tests will fail:

```
  $ ./check_registers 
  Pointer tagging not supported, proceeding without it.
  call_cs_rax: FAIL
  jump_cs_rax: FAIL
  mov_cs_rax: FAIL
  ...
```

Running `./check_registers notag` will pass untagged pointers to tests, so they
will pass:

```
  $ ./check_registers notag
  Pointer tagging not supported, proceeding without it.
  call_cs_rax: PASS
  jump_cs_rax: PASS
  mov_cs_rax: PASS
```

Running `./check_registers` on a tagging-enabled host will produce a mix of
passing and failing tests. To check which tests are expected to pass or fail,
run `./check_registers expect`:

```
  $ ./check_registers expect
  Pointer tagging not supported, proceeding without it.
  call_cs_rax: FAIL (expected)
  jump_cs_rax: FAIL (expected)
  mov_cs_rax: FAIL (unexpected)
```

One can also pass the list of individual test cases to `check_registers`:

```
  $ ./check_registers ret_cs
  Pointer tagging not supported, proceeding without it.
  ret_cs: FAIL
```

## Test cases

Most test case names consist of three parts: operation, segment register prefix
and register name. One exception is `ret_cs`, which does not have register
inputs and is using an implicit CS: segment prefix.

There are three data flow test groups, which are expected to pass on a
tagging-enabled host:
 - `mov_$seg_$reg` - performs `movq $seg:(%$reg), %rbx`,
 - `movaps_$seg_$reg` - performs `movaps $seg:(%$reg), %xmm0`,
 - `tls_fs_$reg` -   performs `movq fs:(%$reg)`.

, and three control flow test groups, which are expected to fail:
 - `call_cs_$reg` - performs `callq *%$reg` (`$reg` cannot be `%rsp`),
 - `jump_cs_$reg` - performs `jmpq *%$reg`,
 - `ret_cs`       - performs `ret`.

For the data flow tests the address in `$reg` is tagged (is in the
non-canonical form). `mov` and `movaps` tests accept userspace pointers
with bits 57:58 set to 1. `tls` tests accept negative offsets with bits
57 and 58 set to 0. `mov` and `movaps` tests also support different segment
prefixes, which should not affect the test result.

Control flow tests accept a tagged pointer to executable code that is passed via
a general purpose register (for `call` and `jump`) or is stored on the top of
the stack (for `ret`). The corresponding instructions do not support segment
prefixes.

## Debugging

To run an individual test under `gdb`, e.g. `movaps_cs_rcx`:

```
  $ gdb ./check_registers
  (gdb) set follow-fork-mode child
  (gdb) br _Z13movaps_cs_rcxPv
  (gdb) r movaps_cs_rcx
  ...
  Thread 2.1 "check_registers" hit Breakpoint 1, 0x0000555555557824 in movaps_cs_rcx(void*) ()
```

To figure out the name of a function corresponding to the particular test, check
the source or the output of `nm check_registers`.

---

--- METRICS ---
- Files Extracted: 5
- Estimated Token Budget: ~2924 tokens
- Canonical Reference: https://codewiki.google/github.com/google/sanitizers
