sanitizers Documentation

AddressSanitizer, ThreadSanitizer, MemorySanitizer

12,504 stars C C 5 files ยท ~3,004 tokens
RAW Doc

Technical Documentation: google/sanitizers

โ„น๏ธ Provenance: Multi-Tier Ingestion ยท CodeWiki Reference

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 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.
  • GCC: For bugs related to the GCC port of the sanitizers, please report them to the GCC 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.
  • 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.

Documentation (Archived):

  • AddressSanitizer (detects addressability issues) and LeakSanitizer (detects memory leaks)
  • ThreadSanitizer (detects data races and deadlocks) for C++ and Go
  • MemorySanitizer (detects use of uninitialized memory)
  • HWASAN, or Hardware-assisted AddressSanitizer, a newer variant of AddressSanitizer that consumes much less memory
  • UBSan, or UndefinedBehaviorSanitizer

Kernel Sanitizers (Archived Documentation):

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.

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.

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,
  2. GWP-ASan,
  3. MTE
    (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/[email protected]/

Building

text
$ g++ check_registers.cc -o check_registers

Running

text
$ ./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:

text
$ ./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:

text
$ ./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:

text
$ ./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:

text
$ ./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:

text
$ 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 ---