1*da58b97aSjoerg================
2*da58b97aSjoergMemTagSanitizer
3*da58b97aSjoerg================
4*da58b97aSjoerg
5*da58b97aSjoerg.. contents::
6*da58b97aSjoerg   :local:
7*da58b97aSjoerg
8*da58b97aSjoergIntroduction
9*da58b97aSjoerg============
10*da58b97aSjoerg
11*da58b97aSjoerg**Note:** this page describes a tool under development. Part of this
12*da58b97aSjoergfunctionality is planned but not implemented.  Hardware capable of
13*da58b97aSjoergrunning MemTagSanitizer does not exist as of Oct 2019.
14*da58b97aSjoerg
15*da58b97aSjoergMemTagSanitizer is a fast memory error detector and **a code hardening
16*da58b97aSjoergtool** based on the Armv8.5-A `Memory Tagging Extension`_. It
17*da58b97aSjoergdetects a similar class of errors as `AddressSanitizer`_ or `HardwareAssistedAddressSanitizer`_, but with
18*da58b97aSjoerg**much** lower overhead.
19*da58b97aSjoerg
20*da58b97aSjoergMemTagSanitizer overhead is expected to be in low single digits, both
21*da58b97aSjoergCPU and memory. There are plans for a debug mode with slightly higher
22*da58b97aSjoergmemory overhead and better diagnostics. The primary use case of
23*da58b97aSjoergMemTagSanitizer is code hardening in production binaries, where it is
24*da58b97aSjoergexpected to be a strong mitigation for both stack and heap-based
25*da58b97aSjoergmemory bugs.
26*da58b97aSjoerg
27*da58b97aSjoerg
28*da58b97aSjoergUsage
29*da58b97aSjoerg=====
30*da58b97aSjoerg
31*da58b97aSjoergCompile and link your program with ``-fsanitize=memtag`` flag. This
32*da58b97aSjoergwill only work when targeting AArch64 with MemTag extension. One
33*da58b97aSjoergpossible way to achieve that is to add ``-target
34*da58b97aSjoergaarch64-linux -march=armv8+memtag`` to compilation flags.
35*da58b97aSjoerg
36*da58b97aSjoergImplementation
37*da58b97aSjoerg==============
38*da58b97aSjoerg
39*da58b97aSjoergSee `HardwareAssistedAddressSanitizer`_ for a general overview of a
40*da58b97aSjoergtag-based approach to memory safety.  MemTagSanitizer follows a
41*da58b97aSjoergsimilar implementation strategy, but with the tag storage (shadow)
42*da58b97aSjoergprovided by the hardware.
43*da58b97aSjoerg
44*da58b97aSjoergA quick overview of MTE hardware capabilities:
45*da58b97aSjoerg
46*da58b97aSjoerg* Every 16 aligned bytes of memory can be assigned a 4-bit Allocation Tag.
47*da58b97aSjoerg* Every pointer can have a 4-bit Address Tag that is in its most significant byte.
48*da58b97aSjoerg* Most memory access instructions generate an exception if Address Tag != Allocation Tag.
49*da58b97aSjoerg* Special instructions are provided for fast tag manipulation.
50*da58b97aSjoerg
51*da58b97aSjoergStack instrumentation
52*da58b97aSjoerg=====================
53*da58b97aSjoerg
54*da58b97aSjoergStack-based memory errors are detected by updating Allocation Tag for
55*da58b97aSjoergeach local variable to a random value at the start of its lifetime,
56*da58b97aSjoergand resetting it to the stack pointer Address Tag at the end of
57*da58b97aSjoergit. Unallocated stack space is expected to match the Address Tag of
58*da58b97aSjoergSP; this allows to skip tagging of any variable when memory safety can
59*da58b97aSjoergbe statically proven.
60*da58b97aSjoerg
61*da58b97aSjoergAllocating a truly random tag for each stack variable in a large
62*da58b97aSjoergfunction may incur significant code size overhead, because it means
63*da58b97aSjoergthat each variable's address is an independent, non-rematerializable
64*da58b97aSjoergvalue; thus a function with N local variables will have extra N live
65*da58b97aSjoergvalues to keep through most of its life time.
66*da58b97aSjoerg
67*da58b97aSjoergFor this reason MemTagSanitizer generates at most one random tag per
68*da58b97aSjoergfunction, called a "base tag". Other stack variables, if there are
69*da58b97aSjoergany, are assigned tags at a fixed offset from the base.
70*da58b97aSjoerg
71*da58b97aSjoergPlease refer to `this document
72*da58b97aSjoerg<https://github.com/google/sanitizers/wiki/Stack-instrumentation-with-ARM-Memory-Tagging-Extension-(MTE)>`_
73*da58b97aSjoergfor more details about stack instrumentation.
74*da58b97aSjoerg
75*da58b97aSjoergHeap tagging
76*da58b97aSjoerg============
77*da58b97aSjoerg
78*da58b97aSjoerg**Note:** this part is not implemented as of Oct 2019.
79*da58b97aSjoerg
80*da58b97aSjoergMemTagSanitizer will use :doc:`ScudoHardenedAllocator`
81*da58b97aSjoergwith additional code to update memory tags when
82*da58b97aSjoerg
83*da58b97aSjoerg* New memory is obtained from the system.
84*da58b97aSjoerg* An allocation is freed.
85*da58b97aSjoerg
86*da58b97aSjoergThere is no need to change Allocation Tags for the bulk of the
87*da58b97aSjoergallocated memory in malloc(), as long as a pointer with the matching
88*da58b97aSjoergAddress Tag is returned.
89*da58b97aSjoerg
90*da58b97aSjoergMore information
91*da58b97aSjoerg================
92*da58b97aSjoerg
93*da58b97aSjoerg* `LLVM Developer Meeting 2018 talk on Memory Tagging <https://llvm.org/devmtg/2018-10/slides/Serebryany-Stepanov-Tsyrklevich-Memory-Tagging-Slides-LLVM-2018.pdf>`_
94*da58b97aSjoerg* `Memory Tagging Whitepaper <https://arxiv.org/pdf/1802.09517.pdf>`_
95*da58b97aSjoerg
96*da58b97aSjoerg.. _Memory Tagging Extension: https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/arm-a-profile-architecture-2018-developments-armv85a
97*da58b97aSjoerg.. _AddressSanitizer: https://clang.llvm.org/docs/AddressSanitizer.html
98*da58b97aSjoerg.. _HardwareAssistedAddressSanitizer: https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html
99