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