NanoTag: Systems Support for Efficient Byte-Granular Overflow Detection on ARM MTE
About
Memory safety bugs, such as buffer overflows and use-after-frees, are the leading causes of software safety issues in production. Software-based approaches, e.g., Address Sanitizer (ASAN), can detect such bugs with high precision, but with prohibitively high overhead. ARM's Memory Tagging Extension (MTE) offers a promising alternative to detect these bugs in hardware with a much lower overhead. In this paper, we perform a thorough investigation of the first production implementation of ARM MTE (Google Pixel 8) and observe that MTE can only achieve coarse precision in bug detection compared with software-based approaches such as ASAN, mainly due to its 16-byte tag granularity. To address this issue, we present NANOTAG, a system to probabilistically detect buffer overflows at byte granularity in unmodified MTE-enabled binaries with minimal changes to memory allocators, introducing an explicit detection-performance tradeoff for in-house testing. NANOTAG detects buffer overflows at byte granularity by setting up a tripwire for tag granules that may require intra-granule overflow detection. The memory access to the tripwire causes additional overflow detection in the software while using MTE's hardware to detect bugs for the rest of the accesses. We implement NANOTAG based on the Scudo Hardened Allocator, the default memory allocator on Android since Android 11. Our evaluation results across popular benchmarks and real-world case studies show that NANOTAG detects nearly as many memory safety bugs as ASAN while incurring similar run-time overhead to Scudo Hardened Allocator in MTE SYNC mode.
Related benchmarks
| Task | Dataset | Result | Rank | |
|---|---|---|---|---|
| Bug Detection | Juliet Test Suite CWE122 - heap-based buffer overflow | Detection Rate97.57 | 5 | |
| Bug Detection | Juliet Test Suite CWE416 - use after free | Detection Rate (CWE416)96.69 | 5 | |
| Bug Detection | Juliet Test Suite CWE415 - double free | Detection Rate98.37 | 5 | |
| Run-time overhead measurement | Geekbench 6 | Run-time Overhead4.99 | 4 | |
| Runtime Overhead Measurement | Memcached mc-benchmark 1.6.14 | Slowdown1.3 | 3 | |
| Runtime Overhead Measurement | RocksDB db_bench 10.10.1 | Slowdown17.75 | 3 | |
| Runtime Overhead Measurement | LevelDB db_bench 1.22 | Slowdown16.93 | 3 | |
| Fuzzing | Magma libpng 1.2.1 | Text Segment Size (KB)277.3 | 2 | |
| Fuzzing | Magma libxml2 1.2.1 | Text Segment Size (MB)1.1 | 2 | |
| Fuzzing | Magma poppler 1.2.1 | Text Segment Size (MB)4.4 | 2 |