# Memory Tagging Extension (MTE)

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS Red Team Expert）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>

## 基本信息

**内存标记扩展（MTE）旨在通过检测和防止与内存相关的错误**（如缓冲区溢出和使用已释放的漏洞）来增强软件的可靠性和安全性。作为**ARM**架构的一部分，MTE提供了一种机制，可以为每个内存分配附加一个**小标记**，并为引用该内存的每个指针附加一个**相应的标记**。这种方法允许在运行时检测非法内存访问，显著降低利用此类漏洞执行任意代码的风险。

### **内存标记扩展的工作原理**

MTE通过**将内存划分为小的固定大小块，每个块分配一个标记**来运作。

当创建指向该内存的指针时，该指针会获得相同的标记。该标记存储在**内存指针的未使用位**中，有效地将指针与其对应的内存块关联起来。

<figure><img src="https://615200056-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1DLBZdNLkY4FUHtMnjPr%2Fuploads%2Fgit-blob-aeefed1e9a7d0da81d6ae5b35bce51a145739711%2Fimage%20(1199).png?alt=media" alt=""><figcaption><p><a href="https://www.youtube.com/watch?v=UwMt0e_dC_Q">https://www.youtube.com/watch?v=UwMt0e_dC_Q</a></p></figcaption></figure>

当程序通过指针访问内存时，MTE硬件会检查**指针的标记是否与内存块的标记匹配**。如果标记**不匹配**，则表示存在**非法内存访问**。

### MTE指针标记

指针内的标记存储在顶部字节的4位中：

<figure><img src="https://615200056-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1DLBZdNLkY4FUHtMnjPr%2Fuploads%2Fgit-blob-9baaeb0ff427b93b693795f74e9e08e7458db57c%2Fimage%20(1200).png?alt=media" alt=""><figcaption><p><a href="https://www.youtube.com/watch?v=UwMt0e_dC_Q">https://www.youtube.com/watch?v=UwMt0e_dC_Q</a></p></figcaption></figure>

因此，这允许**最多16个不同的标记值**。

### MTE内存标记

每**16B的物理内存**对应一个**内存标记**。

内存标记存储在一个**专用的RAM区域**中（无法正常访问）。每16B内存标签占用RAM的3%。

ARM引入以下指令来操作专用RAM内存中的这些标记：

```
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
...
```

## 检查模式

### 同步

CPU 在**执行指令期间**检查标签，如果不匹配，会引发异常。\
这是最慢且最安全的方式。

### 异步

CPU **异步**检查标签，当发现不匹配时，会在系统寄存器中设置异常位。比起同步方式**更快**，但**无法指出**导致不匹配的确切指令，并且不会立即引发异常，给攻击者一些时间来完成攻击。

### 混合

???

## 实施和检测示例

称为基于硬件标签的 KASAN、基于 MTE 的 KASAN 或内核 MTE。\
内核分配器（如 `kmalloc`）将**调用此模块**，该模块将准备要使用的标签（随机）附加到分配的内核空间和返回的指针上。

请注意，它将仅标记足够的内存粒度（每个 16B）以满足请求的大小。因此，如果请求的大小为 35，给出了一个 60B 的 slab，它将使用此标签标记前 16\*3 = 48B，**其余部分**将用所谓的\*\*无效标签（0xE）\*\*标记。

标签**0xF**是**匹配所有指针**。具有此指针的内存允许使用**任何标签**访问其内存（无不匹配）。如果在受攻击的内存中使用此标签，可能会阻止 MET 检测到攻击。

因此，只有**14个值**可用于生成标签，因为 0xE 和 0xF 已保留，导致**标签重用**的概率为 1/17 -> 约**7%**。

如果内核访问**无效标签粒度**，将**检测到不匹配**。如果访问另一个内存位置，如果**内存具有不同的标签**（或无效标签），将**检测到不匹配**。如果攻击者幸运地访问具有相同标签的内存，则不会检测到。概率约为 7%。

另一个 bug 出现在分配内存的**最后一个粒度**中。如果应用程序请求了 35B，它将获得从 32 到 48 的粒度。因此，从 36 到 47 的字节使用相同标签，但未被请求。如果攻击者访问**这些额外字节，不会被检测到**。

当执行\*\*`kfree()`**时，内存将重新标记为无效内存标签，因此在**释放后再次访问内存**时，将**检测到不匹配\*\*。

然而，在释放后再次使用相同**标记重新分配相同的块**时，攻击者将能够使用此访问，而这不会被检测到（约 7% 的机会）。

此外，只有\*\*`slab` 和 `page_alloc`\*\* 使用带标签的内存，但在将来，`vmalloc`、`stack` 和 `globals` 也将使用（在视频时，这些仍然可能被滥用）。

当**检测到不匹配**时，内核将**恐慌**以防止进一步利用和重试利用（MTE 不会产生误报）。

## 参考

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