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