Arm v9 memperkenalkan Arm Memory Tagging Extension (MTE), implementasi hardware memori yang diberi tag.
Pada tingkat tinggi, MTE memberi tag pada setiap alokasi/dealokasi memori dengan metadata tambahan. MTE menetapkan tag ke lokasi memori, yang kemudian dapat dikaitkan dengan pointer yang mereferensikan lokasi memori tersebut. Pada waktu proses, CPU memeriksa apakah pointer dan tag metadata cocok pada setiap pemuatan dan penyimpanan.
Di Android 12, pengalokasi memori heap kernel dan ruang pengguna dapat menambah metadata ke setiap alokasi. Hal ini membantu mendeteksi bug use-after-free dan buffer-overflow, yang merupakan sumber bug keamanan memori paling umum di codebase kami.
Mode operasi MTE
MTE memiliki tiga mode operasi:
- Mode sinkron (SYNC)
- Mode asinkron (ASYNC)
- Mode asimetris (ASYMM)
Mode sinkron (SYNC)
Mode ini dioptimalkan untuk kebenaran deteksi bug atas performa dan
dapat digunakan sebagai alat deteksi bug yang presisi, saat overhead performa yang lebih tinggi dapat diterima. Jika diaktifkan, MTE SYNC berfungsi sebagai mitigasi keamanan.
Jika ada ketidakcocokan tag, prosesor akan segera membatalkan eksekusi dan
menghentikan proses dengan SIGSEGV (kode
SEGV_MTESERR) dan informasi lengkap tentang akses memori dan
alamat faulting.
Sebaiknya gunakan mode ini selama pengujian sebagai alternatif untuk HWASan/KASAN atau dalam produksi saat proses target merepresentasikan kerentanan platform terhadap serangan. Selain itu, jika mode ASYNC telah menunjukkan adanya bug, laporan bug yang akurat dapat diperoleh dengan menggunakan API runtime untuk mengalihkan eksekusi ke mode SYNC.
Saat berjalan dalam mode SYNC, pengalokasi Android akan merekam stack trace untuk semua alokasi dan dealokasi serta menggunakannya untuk memberikan laporan error yang lebih baik yang menyertakan penjelasan tentang error memori, seperti use-after-free atau buffer-overflow, dan stack trace peristiwa memori yang relevan. Laporan tersebut memberikan informasi yang lebih kontekstual dan membuat bug 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 entri kernel terdekat (misalnya, syscall atau interupsi timer), yang menghentikan
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, dengan kepadatan bug keamanan memori yang diketahui rendah, yang dicapai dengan menggunakan mode SYNC selama pengujian.
Mode asimetris (ASYMM)
Fitur tambahan di Arm v8.7-A, mode MTE asimetris memberikan pemeriksaan sinkron pada pembacaan memori, dan pemeriksaan asinkron penulisan memori, dengan performa yang mirip dengan mode ASYNC. Dalam sebagian besar situasi, mode ini merupakan peningkatan dari mode ASYNC, dan sebaiknya gunakan mode ini, bukan ASYNC, jika tersedia.
Oleh karena itu, tidak ada API yang dijelaskan di bawah yang menyebutkan mode asimetris. Sebagai gantinya, OS dapat dikonfigurasi untuk selalu menggunakan mode asimetris saat asinkron diminta. Untuk mengetahui informasi selengkapnya, lihat Mengonfigurasi tingkat MTE pilihan khusus CPU.
MTE di ruang pengguna
Bagian berikut menjelaskan cara 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 mengaktifkan MTE di bawah).
Mengaktifkan MTE menggunakan sistem build
Sebagai properti di seluruh proses, MTE dikontrol oleh setelan waktu build dari executable utama. Opsi berikut memungkinkan perubahan setelan ini untuk executable individual, atau untuk seluruh subdirektori di pohon sumber. Setelan ini diabaikan pada library, atau target apa pun yang bukan executable maupun pengujian.
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 di Android.mk:
| Mode MTE | Setelan |
|---|---|
Asynchronous MTE |
LOCAL_SANITIZE := memtag_heap |
Synchronous MTE |
LOCAL_SANITIZE := memtag_heapLOCAL_SANITIZE_DIAG := memtag_heap |
2. Mengaktifkan MTE di subdirektori di pohon sumber menggunakan variabel produk:
| Mode MTE | Daftar sertakan | Daftar kecualikan |
|---|---|---|
| asinkron | PRODUCT_MEMTAG_HEAP_ASYNC_INCLUDE_PATHS
MEMTAG_HEAP_ASYNC_INCLUDE_PATHS |
PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS
MEMTAG_HEAP_EXCLUDE_PATHS |
| sinkron | 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 executable:
| Mode MTE | Setelan |
|---|---|
| MTE Asinkron | PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS
MEMTAG_HEAP_EXCLUDE_PATHS |
| MTE Sinkron |
Contoh, (penggunaan serupa dengan PRODUCT_CFI_INCLUDE_PATHS)
PRODUCT_MEMTAG_HEAP_SYNC_INCLUDE_PATHS=vendor/$(vendor)
PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS=vendor/$(vendor)/projectA \
vendor/$(vendor)/projectBMengaktifkan MTE menggunakan properti sistem
Setelan build di atas dapat diganti saat runtime dengan menetapkan properti sistem berikut:
arm64.memtag.process.<basename> = (off|sync|async)
Dengan basename adalah nama dasar executable.
Misalnya, untuk menetapkan /system/bin/ping atau /data/local/tmp/ping
agar menggunakan MTE asinkron, gunakan adb shell setprop arm64.memtag.process.ping async.
Mengaktifkan MTE menggunakan variabel lingkungan
Cara lain untuk mengganti setelan build untuk proses native (non-aplikasi)
adalah dengan menentukan variabel lingkungan: MEMTAG_OPTIONS=(off|sync|async)
Jika variabel lingkungan dan properti sistem ditentukan, variabel akan diprioritaskan.
Mengaktifkan MTE untuk aplikasi
Jika tidak ditentukan, MTE akan dinonaktifkan secara default, tetapi
aplikasi yang ingin menggunakan MTE dapat melakukannya dengan menetapkan android:memtagMode
di bawah tag <application> atau
<process> di
AndroidManifest.xml.
android:memtagMode=(off|default|sync|async)
Jika ditetapkan pada tag <application>, atribut akan memengaruhi semua proses yang digunakan oleh aplikasi, dan dapat diganti untuk setiap proses dengan menetapkan tag <process>.
Untuk eksperimen, kompatibilitas
perubahan dapat digunakan untuk menetapkan nilai default atribut memtagMode untuk aplikasi yang tidak
menentukan nilai apa pun dalam manifes (atau menentukan default).
Fitur ini berada di bagian Sistem > Lanjutan > Opsi developer
> Perubahan Kompatibilitas Aplikasi di menu setelan global. Menetapkan
NATIVE_MEMTAG_ASYNC atau NATIVE_MEMTAG_SYNC akan mengaktifkan MTE
untuk aplikasi tertentu. Anda juga dapat menyetelnya menggunakan perintah am
sebagai berikut:
$ adb shell am compat enable NATIVE_MEMTAG_[A]SYNC my.app.name
Membangun image sistem MTE
Sebaiknya aktifkan MTE pada semua biner native selama pengembangan dan pengaktifan. Hal ini membantu mendeteksi bug keamanan memori lebih awal dan memberikan cakupan pengguna yang realistis jika diaktifkan dalam 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 apa pun dalam sistem build, SANITIZE_TARGET dapat
digunakan sebagai variabel lingkungan atau setelan make (misalnya, dalam file product.mk).
Hal ini mengaktifkan MTE untuk semua proses native, tetapi tidak untuk
aplikasi (yang di-fork dari zygote64) yang MTE-nya dapat diaktifkan dengan mengikuti petunjuk di Mengaktifkan MTE untuk aplikasi.
Mengonfigurasi tingkat MTE pilihan khusus CPU
Di beberapa CPU, performa MTE dalam mode ASYMM atau bahkan SYNC mungkin mirip dengan performa ASYNC. Hal ini membuat pengaktifan pemeriksaan yang lebih ketat pada CPU tersebut menjadi bermanfaat saat mode pemeriksaan yang kurang ketat diminta, untuk mendapatkan manfaat deteksi error dari pemeriksaan yang lebih ketat tanpa kekurangan performa.
Secara default, proses yang dikonfigurasi untuk berjalan dalam mode ASYNC berjalan dalam mode ASYNC
di semua CPU. Untuk mengonfigurasi kernel agar menjalankan proses ini dalam mode SYNC di
CPU tertentu, nilai sinkronisasi harus ditulis ke
sysfs entri
/sys/devices/system/cpu/cpu<N>/mte_tcf_preferred saat waktu
booting. Hal ini dapat dilakukan dengan skrip init. Misalnya, untuk mengonfigurasi CPU 0-1
agar menjalankan proses mode ASYNC dalam mode SYNC, dan CPU 2-3 agar menggunakan mode ASYMM,
hal berikut dapat ditambahkan ke klausa init 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 berisi stack trace yang tepat dari lokasi error memori. Namun, tombstone tersebut tidak menyertakan stack trace alokasi atau dealokasi. Stack trace 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 kebenaran.
int mallopt(M_MEMTAG_TUNING, level)
dengan level adalah:
M_MEMTAG_TUNING_BUFFER_OVERFLOWM_MEMTAG_TUNING_UAF
Memilih strategi alokasi tag.
- Setelan default adalah
M_MEMTAG_TUNING_BUFFER_OVERFLOW. M_MEMTAG_TUNING_BUFFER_OVERFLOWmemungkinkan deteksi deterministik deteksi bug buffer overflow dan underflow linear dengan menetapkan nilai tag yang berbeda ke alokasi yang berdekatan. Mode ini memiliki peluang yang sedikit lebih rendah untuk mendeteksi bug use-after-free karena hanya setengah dari nilai tag yang mungkin tersedia untuk setiap lokasi memori. MTE tidak dapat mendeteksi overflow dalam butiran tag yang sama (chunk yang selaras 16 byte), dan dapat melewatkan overflow kecil meskipun dalam mode ini. Overflow tersebut tidak dapat menjadi penyebab kerusakan memori, karena memori dalam satu butiran tidak pernah digunakan untuk beberapa alokasi.M_MEMTAG_TUNING_UAFmemungkinkan tag yang diacak secara independen untuk probabilitas seragam ~93% dalam mendeteksi bug spasial (buffer overflow) dan temporal (use after free).
Selain API yang dijelaskan di atas, pengguna berpengalaman mungkin ingin mengetahui hal berikut:
- Menetapkan register hardware
PSTATE.TCOdapat menekan pemeriksaan tag untuk sementara (contoh). Misalnya, saat menyalin rentang memori dengan konten tag yang tidak diketahui, atau mengatasi bottleneck performa dalam loop aktif. - Saat menggunakan
M_HEAP_TAGGING_LEVEL_SYNC, pengendali error sistem memberikan informasi tambahan seperti stack trace alokasi dan dealokasi. Fungsi ini memerlukan akses ke bit tag dan diaktifkan dengan meneruskan flagSA_EXPOSE_TAGBITSsaat menetapkan pengendali sinyal. Sebaiknya program apa pun yang menetapkan pengendali sinyalnya sendiri dan mendelegasikan error yang tidak diketahui ke sistem melakukan hal yang sama.
MTE di kernel
Untuk mengaktifkan KASAN yang dipercepat MTE untuk kernel, konfigurasi kernel dengan
CONFIG_KASAN=y, CONFIG_KASAN_HW_TAGS=y. Konfigurasi ini
diaktifkan secara default pada kernel GKI, mulai dari Android
12-5.10.
Anda dapat mengontrolnya saat 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 stack trace (default:on)- pengumpulan stack trace juga memerlukan
stack_depot_disable=off.
- pengumpulan stack trace juga memerlukan
kasan.fault=[report|panic]- apakah hanya mencetak laporan, atau juga membuat kernel panik (default:report). Terlepas dari opsi ini, pemeriksaan tag akan dinonaktifkan setelah error pertama dilaporkan.
Penggunaan yang direkomendasikan
Sebaiknya gunakan mode SYNC selama pengaktifan, pengembangan, dan pengujian. Opsi ini harus diaktifkan secara global untuk semua proses menggunakan variabel lingkungan atau dengan sistem build. Dalam mode ini, bug terdeteksi lebih awal dalam proses pengembangan, codebase distabilkan lebih cepat, dan biaya untuk mendeteksi bug nanti dalam produksi dihindari.
Sebaiknya gunakan mode ASYNC dalam produksi. Mode ini menyediakan alat overhead rendah untuk mendeteksi keberadaan bug keamanan memori dalam suatu proses serta pertahanan mendalam lebih lanjut. Setelah bug terdeteksi, developer dapat memanfaatkan API runtime untuk beralih ke mode SYNC dan mendapatkan stack trace yang akurat dari kumpulan pengguna yang diambil sampelnya.
Sebaiknya konfigurasi tingkat MTE pilihan khusus CPU untuk SoC. Mode Asymm biasanya memiliki karakteristik performa yang sama dengan ASYNC, dan hampir selalu lebih disukai. Core kecil yang berurutan sering kali menunjukkan performa yang serupa dalam ketiga mode, dan dapat dikonfigurasi untuk lebih memilih SYNC.
Developer harus memeriksa keberadaan error dengan memeriksa
/data/tombstones,
logcat atau dengan memantau pipeline DropboxManager
vendor untuk bug pengguna akhir. Untuk mengetahui info selengkapnya tentang proses debug kode native Android, lihat
informasi di sini.
Komponen platform yang mengaktifkan MTE
Di Android 12, sejumlah komponen sistem penting keamanan menggunakan MTE ASYNC untuk mendeteksi error pengguna akhir dan bertindak sebagai lapisan pertahanan mendalam tambahan. Komponen ini adalah:
- Daemon dan utilitas jaringan (kecuali
netd) - Bluetooth, SecureElement, NFC HAL, dan aplikasi sistem
- Daemon
statsd system_serverzygote64(untuk memungkinkan aplikasi memilih menggunakan MTE)
Target ini dipilih berdasarkan kriteria berikut:
- Proses yang memiliki hak istimewa (didefinisikan sebagai proses yang memiliki akses ke sesuatu yang tidak dimiliki domain SELinux unprivileged_app)
- Proses input yang tidak tepercaya (Aturan dua)
- Perlambatan performa yang dapat diterima (perlambatan tidak membuat latensi yang terlihat oleh pengguna )
Sebaiknya vendor mengaktifkan MTE dalam produksi untuk lebih banyak komponen, dengan mengikuti kriteria yang disebutkan di atas. Selama pengembangan, sebaiknya uji komponen ini menggunakan mode SYNC, untuk mendeteksi bug yang mudah diperbaiki, dan menilai dampak ASYNC terhadap performanya.
Kami berencana untuk memperluas daftar komponen sistem yang mengaktifkan MTE, yang dipandu oleh karakteristik performa desain hardware mendatang.