Memory Tagging Extension (MTE) - HackTricks

# Memory Tagging Extension (MTE)

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.

## Basic Information

Memory Tagging Extension (MTE) is designed to enhance software reliability and security by detecting and preventing memory-related errors, such as buffer overflows and use-after-free vulnerabilities. MTE, as part of the ARM architecture, provides a mechanism to attach a small tag to each memory allocation and a corresponding tag to each pointer referencing that memory. This approach allows for the detection of illegal memory accesses at runtime, significantly reducing the risk of exploiting such vulnerabilities for executing arbitrary code.

### How Memory Tagging Extension Works

MTE operates by dividing memory into small, fixed-size blocks, with each block assigned a tag, typically a few bits in size.

When a pointer is created to point to that memory, it gets the same tag. This tag is stored in the unused bits of a memory pointer, effectively linking the pointer to its corresponding memory block.

https://www.youtube.com/watch?v=UwMt0e_dC_Q

When a program accesses memory through a pointer, the MTE hardware checks that the pointer's tag matches the memory block's tag. If the tags do not match, it indicates an illegal memory access.

### MTE Pointer Tags

Tags inside a pointer are stored in 4 bits inside the top byte:

https://www.youtube.com/watch?v=UwMt0e_dC_Q

Therefore, this allows up to 16 different tag values.

### MTE Memory Tags

Every 16B of physical memory have a corresponding memory tag.

The memory tags are stored in a dedicated RAM region (not accessible for normal usage). Having 4bits tags for every 16B memory tags up to 3% of RAM.

ARM introduces the following instructions to manipulate these tags in the dedicated RAM memory:

    STG [<Xn/SP>], #<simm>    Store Allocation (memory) Tag
    LDG <Xt>, [<Xn/SP>]       Load Allocatoin (memory) Tag
    IRG <Xd/SP>, <Xn/SP>      Insert Random [pointer] Tag
    ...

## Checking Modes

### Sync

The CPU check the tags during the instruction executing, if there is a mismatch, it raises an exception.
This is the slowest and most secure.

### Async

The CPU check the tags asynchronously, and when a mismatch is found it sets an exception bit in one of the system registers. It's faster than the previous one but it's unable to point out the exact instruction that cause the mismatch and it doesn't raise the exception immediately, giving some time to the attacker to complete his attack.

### Mixed

???

## Implementation & Detection Examples

Called Hardware Tag-Based KASAN, MTE-based KASAN or in-kernel MTE.
The kernel allocators (like `kmalloc`) will call this module which will prepare the tag to use (randomly) attach it to the kernel space allocated and to the returned pointer.

Note that it'll only mark enough memory granules (16B each) for the requested size. So if the requested size was 35 and a slab of 60B was given, it'll mark the first 16*3 = 48B with this tag and the rest will be marked with a so-called invalid tag (0xE).

The tag 0xF is the match all pointer. A memory with this pointer allows any tag to be used to access its memory (no mismatches). This could prevent MET from detecting an attack if this tags is being used in the attacked memory.

Therefore there are only 14 values that can be used to generate tags as 0xE and 0xF are reserved, giving a probability of reusing tags to 1/17 -> around 7%.

If the kernel access to the invalid tag granule, the mismatch will be detected. If it access another memory location, if the memory has a different tag (or the invalid tag) the mismatch will be detected. If the attacker is lucky and the memory is using the same tag, it won't be detected. Chances are around 7%

Another bug occurs in the last granule of the allocated memory. If the application requested 35B, it was given the granule from 32 to 48. Therefore, the bytes from 36 til 47 are using the same tag but they weren't requested. If the attacker access these extra bytes, this isn't detected.

When `kfree()` is executed, the memory is retagged with the invalid memory tag, so in a use-after-free, when the memory is accessed again, the mismatch is detected.

However, in a use-after-free, if the same chunk is reallocated again with the SAME tag as previously, an attacker will be able to use this access and this won't be detected (around 7% chance).

Moreover, only `slab` and `page_alloc` uses tagged memory but in the future this will also be used in `vmalloc`, `stack` and `globals` (at the moment of the video these can still be abused).

When a mismatch is detected the kernel will panic to prevent further exploitation and retries of the exploit (MTE doesn't have false positives).

## References

- https://www.youtube.com/watch?v=UwMt0e_dC_Q

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.