Aktifkan ekstensi pemberian tag memori

Arm v9 memperkenalkan Arm Memory Ekstensi Pemberian Tag (MTE), sebuah penerapan hardware memori yang diberi tag.

Pada level yang tinggi, MTE menandai setiap alokasi/dealokasi memori dengan metadata tambahan. Ini menetapkan tag ke lokasi memori, yang kemudian dapat yang berkaitan dengan pointer yang mereferensikan lokasi memori tersebut. Saat runtime, CPU memeriksa apakah pointer dan tag metadata cocok pada setiap pemuatan dan penyimpanan.

Di Android 12, pengalokasi memori heap kernel dan userspace dapat meningkatkan setiap alokasi dengan metadata. Ini membantu mendeteksi {i> use-after-free<i} dan {i>bug<i}-{i>buffer-overflow<i}, yang merupakan sumber {i> bug<i} keamanan memori paling umum di codebase kita.

Mode operasi MTE

MTE memiliki tiga mode operasi:

  • Mode sinkron (SYNC)
  • Mode asinkron (ASYNC)
  • Mode asimetris (ASYMM)

Mode sinkron (SYNC)

Mode ini dioptimalkan untuk ketepatan deteksi {i>bug<i} terhadap kinerja dan dapat digunakan sebagai alat deteksi bug yang tepat, ketika overhead performa lebih tinggi masih dapat diterima. Jika diaktifkan, MTE SYNC akan berfungsi sebagai mitigasi keamanan. Jika ada ketidakcocokan tag, pemroses akan segera membatalkan eksekusi dan menghentikan proses dengan SIGSEGV (kode SEGV_MTESERR) dan informasi lengkap tentang akses memori dan faulting address.

Sebaiknya gunakan mode ini selama pengujian sebagai alternatif HWASan/KASAN atau dalam produksi saat proses target mewakili kelompok yang rentan permukaan serangan. Selain itu, ketika mode ASYNC telah mengindikasikan adanya {i>bug<i}, laporan bug yang akurat dapat diperoleh dengan menggunakan API runtime untuk dan mengeksekusinya ke mode SYNC.

Saat berjalan dalam mode SYNC, Alokator Android mencatat pelacakan tumpukan untuk semua alokasi dan dealokasi, serta menggunakannya untuk memberikan laporan {i>error<i} yang lebih baik, yang menyertakan penjelasan tentang memori error, seperti use-after-free, atau buffer-overflow, dan pelacakan tumpukan peristiwa memori yang relevan. Laporan tersebut memberikan lebih banyak informasi kontekstual dan membuat {i>bug<i} lebih mudah dilacak dan diperbaiki.

Mode asinkron (ASYNC)

Mode ini dioptimalkan untuk performa atas akurasi laporan bug dan dapat digunakan sebagai deteksi overhead rendah untuk bug keamanan memori.
Jika ada ketidakcocokan tag, pemroses akan melanjutkan eksekusi hingga yang terdekat entri {i>kernel<i} (misalnya, syscall atau interupsi timer), di mana ia berakhir proses dengan SIGSEGV (kode SEGV_MTEAERR) tanpa merekam alamat faulting atau akses memori.
Sebaiknya gunakan mode ini dalam produksi pada codebase yang telah diuji dengan baik di mana kepadatan bug keamanan memori diketahui rendah, yang dicapai dengan menggunakan mode SYNC selama pengujian.

Mode asimetris (ASYMM)

Fitur tambahan di Arm v8.7-A, mode MTE Asimetris menyediakan memeriksa pembacaan memori, dan pemeriksaan asinkron atas penulisan memori, dengan kinerja yang serupa dengan mode ASYNC. Di kebanyakan situasi, merupakan peningkatan dari mode ASYNC, dan sebaiknya Anda menggunakannya ASYNC setiap kali tersedia.

Karena alasan ini, tidak satu pun API yang dijelaskan di bawah ini yang menyebutkan mode. Sebaliknya, OS dapat dikonfigurasi untuk selalu menggunakan mode Asimetris ketika Asinkron diminta. Silakan lihat "Mengkonfigurasi CPU- tingkat MTE yang diinginkan" untuk informasi selengkapnya.

MTE di ruang pengguna

Bagian berikut menjelaskan bagaimana MTE dapat diaktifkan untuk proses sistem dan aplikasi. MTE dinonaktifkan secara default, kecuali jika salah satu opsi di bawah ditetapkan untuk proses tertentu (lihat komponen yang diaktifkan MTE di bawah).

Mengaktifkan MTE menggunakan sistem build

Sebagai properti lingkup proses, MTE dikontrol oleh setelan waktu build file utama yang dapat dieksekusi. Opsi berikut memungkinkan perubahan pengaturan untuk {i>executable<i} individual, atau untuk seluruh subdirektori dalam pohon sumber. Tujuan diabaikan pada library, atau target apa pun yang tidak dapat dieksekusi atau uji coba.

1. Mengaktifkan MTE di Android.bp (contoh), untuk project tertentu:

Mode MTE Setelan
MTE Asinkron
  sanitize: {
  memtag_heap: true,
  }
MTE sinkron
  sanitize: {
  memtag_heap: true,
  diag: {
  memtag_heap: true,
  },
  }

atau dalam Android.mk:

Mode MTE Setelan
Asynchronous MTE LOCAL_SANITIZE := memtag_heap
Synchronous MTE LOCAL_SANITIZE := memtag_heap
LOCAL_SANITIZE_DIAG := memtag_heap

2. Mengaktifkan MTE pada subdirektori di hierarki sumber menggunakan produk variabel:

Mode MTE Sertakan daftar Kecualikan daftar
asinkron PRODUCT_MEMTAG_HEAP_ASYNC_INCLUDE_PATHS MEMTAG_HEAP_ASYNC_INCLUDE_PATHS PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
sinkronkan PRODUCT_MEMTAG_HEAP_SYNC_INCLUDE_PATHS MEMTAG_HEAP_SYNC_INCLUDE_PATHS

atau

Mode MTE Setelan
MTE Asinkron MEMTAG_HEAP_ASYNC_INCLUDE_PATHS
MTE sinkron MEMTAG_HEAP_SYNC_INCLUDE_PATHS

atau dengan menentukan jalur pengecualian file yang dapat dieksekusi:

Mode MTE Setelan
MTE Asinkron PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
MTE sinkron

Contoh, (penggunaan yang mirip dengan PRODUCT_CFI_INCLUDE_PATHS)

  PRODUCT_MEMTAG_HEAP_SYNC_INCLUDE_PATHS=vendor/$(vendor)
  PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS=vendor/$(vendor)/projectA \
                                    vendor/$(vendor)/projectB

Mengaktifkan MTE menggunakan properti sistem

Setelan build di atas dapat diganti saat runtime dengan mengatur properti sistem berikut:

arm64.memtag.process.<basename> = (off|sync|async)

basename adalah singkatan dari nama dasar file yang dapat dieksekusi.

Misalnya, untuk menetapkan /system/bin/ping atau /data/local/tmp/ping untuk menggunakan MTE asinkron, gunakan adb shell setprop arm64.memtag.process.ping async.

Mengaktifkan MTE menggunakan variabel lingkungan

Satu cara lagi untuk mengganti setelan build adalah dengan menentukan lingkungan variabel: MEMTAG_OPTIONS=(off|sync|async) Jika variabel lingkungan dan properti sistem telah ditentukan, metode akan diprioritaskan.

Mengaktifkan MTE untuk aplikasi

Jika tidak ditentukan, MTE akan dinonaktifkan secara default aplikasi yang ingin menggunakan MTE dapat melakukannya dengan menyetel android:memtagMode di bagian <application> atau <process> di AndroidManifest.xml.

android:memtagMode=(off|default|sync|async)

Jika ditetapkan pada tag <application>, memengaruhi semua proses yang digunakan oleh aplikasi, dan dapat diganti untuk proses individu dengan mengatur tag <process>.

Untuk eksperimen, kompatibilitas perubahan dapat digunakan untuk menetapkan nilai default Atribut memtagMode untuk aplikasi yang tidak menetapkan nilai apa pun dalam manifes (atau menentukan default).
ID ini dapat ditemukan di System > Advanced > Developer options > App Compatibility Changes pada menu setelan global. Latar (Setting) NATIVE_MEMTAG_ASYNC atau NATIVE_MEMTAG_SYNC mengaktifkan MTE untuk aplikasi tertentu.
Atau, Anda juga dapat menyetelnya menggunakan am sebagai berikut:

$ adb shell am compat enable NATIVE_MEMTAG_[A]SYNC my.app.name

Membangun image sistem MTE

Sebaiknya aktifkan MTE di semua biner native selama pengembangan dan memunculkannya. Hal ini membantu mendeteksi bug keamanan memori lebih awal dan memberikan cakupan pengguna, jika diaktifkan di build pengujian.

Sebaiknya aktifkan MTE dalam mode Sinkron pada semua biner native selama pengembangan

SANITIZE_TARGET=memtag_heap SANITIZE_TARGET_DIAG=memtag_heap m

Seperti variabel lainnya dalam sistem build, SANITIZE_TARGET dapat berupa digunakan sebagai variabel lingkungan atau setelan make (misalnya dalam product.mk file).
Perlu diketahui bahwa hal ini memungkinkan MTE untuk semua proses native, tetapi tidak untuk aplikasi (yang diambil dari zygote64) yang dapat menggunakan MTE diaktifkan dengan mengikuti petunjuk di atas.

Mengonfigurasi level MTE pilihan khusus CPU

Di beberapa CPU, performa MTE dalam mode ASYMM atau bahkan SYNC mungkin mirip dengan yaitu ASYNC. Hal ini membuat pengaktifan pemeriksaan yang lebih ketat terhadap CPU ketika mode pemeriksaan yang kurang ketat diminta, di untuk mendapatkan manfaat deteksi kesalahan dari pemeriksaan yang lebih ketat tanpa kelemahan kinerja.
Secara default, proses yang dikonfigurasi untuk berjalan dalam mode ASYNC akan berjalan di ASYNC yang sesuai di semua CPU. Untuk mengonfigurasi kernel agar menjalankan proses ini dalam mode SYNC pada di CPU tertentu, sinkronisasi nilai harus ditulis ke sysfs entri /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred saat booting baik. Ini dapat dilakukan dengan skrip init. Misalnya, untuk mengkonfigurasi CPU 0-1 untuk menjalankan proses mode ASYNC dalam mode SYNC, dan CPU 2-3 untuk dijalankan dalam mode ASYMM, hal berikut dapat ditambahkan ke klausa init dari skrip init vendor:

  write /sys/devices/system/cpu/cpu0/mte_tcf_preferred sync
  write /sys/devices/system/cpu/cpu1/mte_tcf_preferred sync
  write /sys/devices/system/cpu/cpu2/mte_tcf_preferred asymm
  write /sys/devices/system/cpu/cpu3/mte_tcf_preferred asymm

Tombstone dari proses mode ASYNC yang berjalan dalam mode SYNC akan berisi pelacakan tumpukan yang akurat dari lokasi kesalahan memori. Namun, mereka tidak akan menyertakan alokasi atau dealokasi pelacakan tumpukan. Pelacakan tumpukan ini hanya tersedia jika proses dikonfigurasi untuk berjalan dalam mode SYNC.

int mallopt(M_THREAD_DISABLE_MEM_INIT, level)

dengan level adalah 0 atau 1.
Menonaktifkan inisialisasi memori di malloc, dan menghindari perubahan tag memori kecuali jika diperlukan untuk ketepatan.

int mallopt(M_MEMTAG_TUNING, level)

dengan level adalah:

  • M_MEMTAG_TUNING_BUFFER_OVERFLOW
  • M_MEMTAG_TUNING_UAF

Memilih strategi alokasi tag.

  • Setelan default-nya adalah M_MEMTAG_TUNING_BUFFER_OVERFLOW.
  • M_MEMTAG_TUNING_BUFFER_OVERFLOW - memungkinkan determenistik deteksi overflow dan bug underflow buffer linear dengan menetapkan tag yang berbeda ke alokasi yang berdekatan. Mode ini memiliki peluang sedikit lebih rendah untuk mendeteksi bug use-after-free karena hanya setengah dari nilai tag yang yang tersedia untuk setiap lokasi memori. Perlu diingat bahwa MTE tidak dapat mendeteksi meluap dalam granule tag yang sama (bongkahan selaras 16 byte), dan dapat melewatkan {i>overflow<i} bahkan dalam mode ini. Overflow tersebut tidak dapat menjadi penyebab memori kerusakan, karena memori dalam satu granule tidak pernah digunakan untuk beberapa alokasi.
  • M_MEMTAG_TUNING_UAF - memungkinkan tag yang diacak secara independen untuk probabilitas ~93% yang seragam dalam mendeteksi spasial (buffer overflow) dan {i>bug<i} temporal (digunakan setelah bebas).

Selain API yang dijelaskan di atas, pengguna berpengalaman mungkin ingin perhatikan hal-hal berikut:

  • Menyetel register hardware PSTATE.TCO dapat sementara menyembunyikan pemeriksaan tag (contoh). Misalnya, saat menyalin rentang memori dengan konten tag yang tidak dikenal, atau mengatasi bottleneck performa dalam hot loop.
  • Saat menggunakan M_HEAP_TAGGING_LEVEL_SYNC, pengendali error sistem memberikan informasi tambahan seperti alokasi dan dealokasi stack trace. Fungsi ini memerlukan akses ke bit tag dan diaktifkan dengan meneruskan SA_EXPOSE_TAGBITS penanda saat mengatur pengendali sinyal. Semua program yang menetapkan sinyalnya sendiri dan mendelegasikan error yang tidak dikenal ke sistem, yang disarankan untuk dilakukan hal yang sama.

MTE di kernel

Untuk mengaktifkan KASAN yang dipercepat MTE untuk {i>kernel<i}, konfigurasikan {i>kernel<i} dengan CONFIG_KASAN=y, CONFIG_KASAN_HW_TAGS=y. Konfigurasi ini diaktifkan secara default pada kernel GKI, dimulai dengan Android 12-5.10.
Hal ini dapat dikontrol pada waktu booting menggunakan argumen command line berikut:

  • kasan=[on|off] - mengaktifkan atau menonaktifkan KASAN (default: on)
  • kasan.mode=[sync|async] - memilih antara mode sinkron dan asinkron (default: sync)
  • kasan.stacktrace=[on|off] - apakah akan mengumpulkan pelacakan tumpukan (default: on)
    • pengumpulan pelacakan tumpukan juga memerlukan stack_depot_disable=off.
  • kasan.fault=[report|panic] - apakah hanya akan mencetak laporan, atau juga membuat kernel panik (default: report). Terlepas dari hal ini, , pemeriksaan tag akan dinonaktifkan setelah error yang pertama kali dilaporkan.

Sebaiknya gunakan mode SYNC selama pembukaan, pengembangan, dan pengujian. Opsi ini harus diaktifkan secara global untuk semua proses yang menggunakan variabel lingkungan atau dengan sistem build. Dalam mode ini, bug terdeteksi di awal proses pengembangan, basis kode distabilkan lebih cepat dan biaya deteksi {i>bug<i} di kemudian hari dalam produksi dapat dihindari.

Sebaiknya gunakan mode ASYNC dalam produksi. Hal ini memberikan dampak overhead untuk mendeteksi keberadaan bug keamanan memori dalam suatu proses serta pertahanan mendalam yang lebih mendalam. Setelah {i>bug<i} terdeteksi, pengembang dapat memanfaatkan API runtime untuk beralih ke mode SYNC dan mendapatkan pelacakan tumpukan yang akurat dari sekumpulan pengguna sebagai sampel.

Kami sangat menyarankan untuk mengkonfigurasi tingkat MTE pilihan khusus CPU untuk SoC. Mode Asymm biasanya memiliki karakteristik kinerja yang sama dengan ASYNC, dan hampir selalu lebih disukai. Inti dalam urutan kecil sering kali menunjukkan tampilan performa dalam ketiga mode tersebut, dan dapat dikonfigurasi untuk memilih SYNC.

Developer harus memeriksa keberadaan error dengan memeriksa /data/tombstones, logcat atau dengan memantau vendor DropboxManager {i>pipelines<i} untuk bug pengguna akhir. Untuk informasi selengkapnya tentang cara men-debug kode native Android, lihat informasinya di sini.

Komponen platform yang mendukung MTE

Di Android 12, sejumlah komponen sistem penting keamanan menggunakan MTE ASYNC untuk mendeteksi tabrakan yang dialami pengguna akhir dan sebagai lapisan tambahan pertahanan mendalam. Komponen tersebut adalah:

  • {i>Daemon<i} dan utilitas jaringan (dengan pengecualian netd)
  • Bluetooth, SecureElement, NFC HAL, dan aplikasi sistem
  • Daemon statsd
  • system_server
  • zygote64 (untuk mengizinkan aplikasi memilih ikut serta menggunakan MTE)

Target ini dipilih berdasarkan kriteria berikut:

  • Proses dengan hak istimewa (didefinisikan sebagai proses yang memiliki akses ke sesuatu yang tidak dimiliki oleh domain SELinux {i>unprivileged_app<i})
  • Memproses input yang tidak dapat dipercaya (Aturan dari dua)
  • Pelambatan performa yang dapat diterima (perlambatan tidak membuat pengguna terlihat latensi)

Sebaiknya vendor mengaktifkan MTE dalam produksi untuk lebih banyak komponen, dengan mengikuti kriteria yang disebutkan di atas. Selama pengembangan, sebaiknya lakukan pengujian komponen ini menggunakan mode SYNC, untuk mendeteksi bug yang diperbaiki dengan mudah, dan menilai ASYNC berdampak pada performanya.
Di masa mendatang, Android berencana memperluas daftar komponen sistem MTE dengan panduan berdasarkan karakteristik kinerja desain perangkat keras yang akan datang.