タグ付きポインタ

Android 11 以降、64 ビットプロセスの場合、すべてのヒープ割り当てに、ARM Top-byte Ignore(TBI)のカーネル サポートを備えたデバイス上のポインタの上位バイトに実装されたタグが設定されます。このタグを変更するアプリは、割り当て解除時にタグのチェックが完了すると終了します。これは、ARM Memory Tagging Extension(MTE)をサポートする今後のハードウェアで必要なものです。

Top-byte ignore

ARM の Top-byte Ignore 機能は、すべての Armv8 AArch64 ハードウェアで 64 ビットコードに対して使用できます。これは、メモリにアクセスするときにハードウェアがポインタの上位バイトを無視することを意味します。

TBI には、ユーザー空間から渡されたタグ付きポインタを正しく処理する互換性のあるカーネルが必要です。4.14(Pixel 4)以降の Android 共通カーネルには、必要な TBI パッチが搭載されています。

カーネルで TBI をサポートするデバイスは、処理開始時に動的に検出され、実装に依存するタグは、すべてのヒープ割り当てのポインタの上位バイトに挿入されます。その後、メモリの割り当てを解除したときに、タグが切り捨てられていないことを確認するチェックが実行されます。

メモリタグ付け拡張機能の対応状況

ARM メモリタグ付け拡張機能(MTE)は、メモリの安全性に関する問題に対処するのに役立ちます。MTE は、スタック、ヒープ、グローバルの各メモリ割り当ての 56~59 番目のアドレスビットをタグ付けすることで機能します。ハードウェアと命令セットは、メモリアクセス時に正しいタグが使用されているかどうかを自動的に確認します。

誤ってポインタの上位バイトに情報を保存する Android アプリは、MTE 対応デバイスで中断することが保証されます。タグ付きポインタを使用すると、MTE デバイスが利用可能になる前に、ポインタの上位バイトの誤った使用の検出と拒否を簡単に行うことができます。

デベロッパー サポート

アプリがクラッシュしてこのリンクが表示された場合は、次のいずれかである可能性があります。

  1. アプリが、システムのヒープ アロケータによって割り当てられていないポインタを解放しようとした。
  2. アプリ内でなんらかの理由でポインタの上位バイトが変更された。ポインタの上位バイトは変更できないため、この問題を解決するには、コードを変更する必要があります。

上位バイトのポインタが誤って使用または変更されている例を次に示します。

  • 特定のタイプへのポインタには、上位 16 個のアドレスビットに保存されているアプリ固有のメタデータがある。
  • ポインタが二重にキャストし、その後回復したが、下位のアドレスビットがない。
  • 再帰処理回数を測定する方法として、異なるスタック フレームとローカル変数のアドレスの差をコードが計算している。

一部のアプリは、ポインタの上位バイトが設定されていると正しく動作しなくなるライブラリに依存している場合があります。こうしたライブラリの根本的な問題は、すばやく修正することが重要です。そのため、targetSdkLevel < 30 を使用するアプリでは、ポインタのタグ付けがデフォルトで有効になりません。また、targetSdkLevel >= 30 を使用してビルドされたアプリ向けに、簡単に移行するための方法が用意されています。

この方法を使用するには、次の行を AndroidManifest.xml ファイルに追加します。

  <application android:allowNativeHeapPointerTagging="false">
  ...
  </application>

これにより、アプリのポインタタグ付け機能が無効になります。ただし、基盤となるコードの健全性の問題には対処していません。この方法は Android の今後のバージョンでは使用できなくなります。こうした性質の問題は MTE に適合しないためです。