Memory Tagging Extension (MTE)

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

基本情報

Memory Tagging Extension (MTE) は、buffer overflows や use-after-free のようなメモリ関連のエラーを 検出および防止する ことでソフトウェアの信頼性とセキュリティを向上させることを目的としています。MTE は ARM アーキテクチャの一部として、各メモリアロケーションに 小さなタグを付与 し、そのメモリを参照する各ポインタに 対応するタグを割り当てる 機構を提供します。この仕組みにより、ランタイムで不正なメモリアクセスを検出でき、任意のコード実行に繋がる脆弱性の悪用リスクを大幅に低減します。

Memory Tagging Extension の仕組み

MTE はメモリを小さな固定サイズのブロックに 分割し、各ブロックにタグを割り当てる ことで動作します。タグは通常数ビット程度です。

そのメモリを指すポインタが作成されると、ポインタにも同じタグが付与されます。このタグは ポインタの未使用ビット に格納され、ポインタと対応するメモリブロックが紐付けられます。

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

プログラムがポインタを介してメモリにアクセスする際、MTE ハードウェアは ポインタのタグとメモリブロックのタグが一致するか をチェックします。タグが 一致しない場合、それは 不正なメモリアクセス を示します。

MTE ポインタタグ

ポインタ内のタグは上位バイトの4ビットに格納されます:

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

したがって、最大 16 種類のタグ値 が利用可能です。

MTE メモリタグ

物理メモリの 16B ごとに 対応する メモリタグ が存在します。

メモリタグは 専用の RAM 領域 に格納され(通常の用途からはアクセス不可)、16B ごとに4ビットのタグを持つため、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
...

Checking Modes

Sync

CPUは命令実行中にタグをチェックし、ミスマッチがあれば例外を発生させます(SIGSEGV with SEGV_MTESERR)。これにより正確な命令とアドレスが即座に分かります。
問題のあるload/storeがブロックされるため、これは最も遅いが最も安全です。

Async

CPUはタグを非同期にチェックし、ミスマッチが見つかるとシステムレジスタの一つに例外ビットをセットします。前者より高速ですが、ミスマッチを引き起こした正確な命令を特定できず、例外を即座に発生させません(SIGSEGV with SEGV_MTEAERR)。そのため攻撃者に攻撃完了の時間を与えてしまいます。

Mixed

Per-core preferences(例えば /sys/devices/system/cpu/cpu*/mte_tcf_preferredsyncasyncasymm を書き込む)によりカーネルはプロセス単位の要求を黙って昇格または降格させます。したがって本番ビルドは通常 ASYNC を要求し、特権コアはワークロードが許すときに SYNC を強制します。

Implementation & Detection Examples

Called Hardware Tag-Based KASAN, MTE-based KASAN or in-kernel MTE.
カーネルアロケータ(kmalloc など)はこのモジュールを呼び出し、使用するタグを(ランダムに)準備して割り当てられたカーネル空間と返却されたポインタに付与します。

注意すべきは、要求サイズに対して十分な数のメモリ粒(各16B)だけをマークすることです。つまり要求サイズが35で60Bのスラブが与えられた場合、最初の16*3 = 48Bにこのタグを付け、残りはいわゆるinvalid tag (0xE)マークされます。

タグ 0xFmatch all pointer です。このポインタを持つメモリは任意のタグでアクセス可能(ミスマッチなし)であり、攻撃対象のメモリにこのタグが使われていると MTE による検出を防ぐ可能性があります。

したがって 0xE と 0xF が予約されているため、タグ生成に使える値は14個しかなく、タグを再利用する確率は 1/17 -> 約 7% になります。

カーネルがinvalid tag granuleにアクセスするとミスマッチ検出されます。別のメモリ位置にアクセスし、そのメモリが異なるタグ(または invalid tag)を持っている場合もミスマッチは検出されます。攻撃者が運良く同じタグを持つメモリに当たれば検出されません。確率は約7%です。

別のバグは割り当てられたメモリの最後の粒に発生します。アプリが35Bを要求すると32〜48の粒が与えられるため、36〜47バイトは同じタグを使っているが要求されていません。攻撃者がこれらの余分なバイトにアクセスしても検出されません

kfree() が実行されるとメモリは無効メモリタグで再タグ付けされるため、use-after-free で再度そのメモリにアクセスするとミスマッチが検出されます。

しかし、use-after-free において同じchunk が以前と SAME tag で再割り当てされると、攻撃者はこのアクセスを利用でき、検出されません(約7%の確率)。

さらに現状では slabpage_alloc のみがタグ付きメモリを使用していますが、将来的には vmallocstackglobals でも使われるようになる(このビデオ作成時点ではまだ悪用可能)でしょう。

ミスマッチが検出されるとカーネルはpanicしてさらなる悪用やエクスプロイトの再試行を防ぎます(MTE は誤検知がありません)。

Speculative Tag Leakage (TikTag)

TikTag (2024) は2つの speculative execution gadgets (TIKTAG-v1/v2) を示し、任意のアドレスの4ビット割り当てタグを <4秒 で >95% の成功率で leak できることを実証しました。攻撃者が選んだキャッシュラインに投機的に触れてプリフェッチ誘発のタイミングを観測することで、Chrome プロセス、Android system services、または Linux カーネルに割り当てられたタグの乱数化を解き、漏洩した値を持つポインタを作成できます。一度タグ空間が総当たりで潰されると、確率的な粒再利用の前提(≈7% の false-negative 率)は崩壊し、従来のヒープエクスプロイト(UAF, OOB)は MTE が有効でもほぼ100% の信頼性を取り戻します。論文はまた、漏れたタグから偽スラブを再タグ付けする proof-of-concept エクスプロイトも示しており、投機的サイドチャネルがハードウェアタグ付けスキームのバイパス経路として依然として有効であることを示しています。

References

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする