Arm v9 memperkenalkan Memory Tagging Extension (MTE) Arm, implementasi hardware memori bertag.
Pada tingkat tinggi, MTE memberi tag pada setiap alokasi/pembatalan alokasi memori dengan metadata tambahan. Fungsi ini menetapkan tag ke lokasi memori, yang kemudian dapat dikaitkan 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, kernel dan alokator memori heap ruang pengguna dapat meningkatkan setiap alokasi dengan metadata. Hal ini membantu mendeteksi bug use-after-free dan buffer-overflow, yang merupakan sumber bug keamanan memori yang 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 ketepatan 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
) serta 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 platform serangan yang rentan. 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, allocator Android mencatat pelacakan tumpukan untuk semua alokasi dan penghapusan alokasi serta menggunakannya untuk memberikan laporan error yang lebih baik yang menyertakan penjelasan error memori, seperti use-after-free, atau buffer-overflow, dan pelacakan tumpukan 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 pada 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, setiap kali tersedia.
Oleh karena itu, tidak ada API yang dijelaskan di bawah yang menyebutkan mode Asimetris. Sebagai gantinya, OS dapat dikonfigurasi agar selalu menggunakan mode Asimetris saat Asinkron diminta. Lihat bagian "Mengonfigurasi tingkat MTE pilihan khusus CPU" untuk mengetahui informasi selengkapnya.
MTE di ruang pengguna
Bagian berikut menjelaskan cara mengaktifkan MTE untuk proses dan aplikasi sistem. 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 seluruh proses, MTE dikontrol oleh setelan waktu build file yang dapat dieksekusi utama. Opsi berikut memungkinkan perubahan setelan ini untuk setiap file yang dapat dieksekusi, atau untuk seluruh subdirektori dalam hierarki sumber. Setelan ini diabaikan di library, atau target apa pun yang tidak dapat dieksekusi atau 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_heap LOCAL_SANITIZE_DIAG := memtag_heap |
2. Mengaktifkan MTE di subdirektori dalam hierarki sumber menggunakan variabel produk:
Mode MTE | Menyertakan daftar | Daftar pengecualian |
---|---|---|
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 serupa 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 menetapkan properti sistem berikut:
arm64.memtag.process.<basename> = (off|sync|async)
Dengan basename
adalah singkatan dari nama dasar file yang dapat dieksekusi.
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
Satu lagi cara untuk mengganti setelan build 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
pada tag <application>
atau
<process>
di
AndroidManifest.xml
.
android:memtagMode=(off|default|sync|async)
Jika ditetapkan pada tag <application>
, atribut tersebut akan memengaruhi semua proses yang digunakan oleh aplikasi, dan dapat diganti untuk setiap proses dengan menetapkan tag <process>
.
Untuk eksperimen, perubahan
kompatibilitas dapat digunakan untuk menetapkan nilai default
atribut memtagMode
untuk aplikasi yang tidak
menentukan nilai apa pun dalam manifes (atau menentukan
default
).
Ini dapat ditemukan di bagian System > Advanced > Developer options
> App Compatibility Changes
di menu setelan global. Menetapkan
NATIVE_MEMTAG_ASYNC
atau NATIVE_MEMTAG_SYNC
akan mengaktifkan MTE
untuk aplikasi tertentu.
Atau, Anda juga dapat menyetelnya menggunakan perintah
am
sebagai berikut:
$ adb shell am compat enable NATIVE_MEMTAG_[A]SYNC my.app.name
Mem-build image sistem MTE
Sebaiknya aktifkan MTE di 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 di semua biner native selama pengembangan
SANITIZE_TARGET=memtag_heap SANITIZE_TARGET_DIAG=memtag_heap m
Seperti variabel lainnya dalam sistem build, SANITIZE_TARGET
dapat
digunakan sebagai variabel lingkungan atau setelan make
(misalnya, dalam
file product.mk
).
Perhatikan bahwa tindakan 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 atas.
Mengonfigurasi level MTE pilihan khusus CPU
Pada beberapa CPU, performa MTE dalam mode ASYMM atau bahkan SYNC mungkin mirip dengan
performa ASYNC. Hal ini membuat pemeriksaan yang lebih ketat pada CPU tersebut menjadi lebih bermanfaat saat mode pemeriksaan yang kurang ketat diminta, untuk mendapatkan manfaat deteksi error dari pemeriksaan yang lebih ketat tanpa
penurunan performa.
Secara default, proses yang dikonfigurasi untuk berjalan dalam mode ASYNC akan berjalan dalam mode
ASYNC di semua CPU. Untuk mengonfigurasi kernel agar menjalankan proses ini dalam mode SYNC pada
CPU tertentu, sinkronisasi nilai harus ditulis ke
entri sysfs
/sys/devices/system/cpu/cpu<N>/mte_tcf_preferred
pada 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 run 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 error memori. Namun, laporan tersebut tidak akan menyertakan pelacakan tumpukan alokasi atau dealokasi. Stack trace ini hanya tersedia jika proses dikonfigurasi untuk berjalan dalam mode SINKRONISASI.
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 akurasi.
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 deteksi deterministik bug overflow dan underflow buffering linear dengan menetapkan nilai tag yang berbeda ke alokasi yang berdekatan. Mode ini memiliki peluang yang sedikit berkurang untuk mendeteksi bug use-after-free karena hanya setengah dari kemungkinan nilai tag yang tersedia untuk setiap lokasi memori. Perlu diingat bahwa MTE tidak dapat mendeteksi overflow dalam granule tag yang sama (bagian yang sejajar 16 byte), dan dapat melewatkan overflow kecil bahkan dalam mode ini. Overflow tersebut tidak dapat menjadi penyebab kerusakan memori, karena memori dalam satu granule tidak pernah digunakan untuk beberapa alokasi.M_MEMTAG_TUNING_UAF
- mengaktifkan tag acak secara independen untuk probabilitas deteksi bug spasial (buffer overflow) dan temporal (use after free) yang seragam ~93%.
Selain API yang dijelaskan di atas, pengguna berpengalaman mungkin ingin mengetahui hal berikut:
- Menetapkan register hardware
PSTATE.TCO
dapat sementara menyembunyikan pemeriksaan tag (contoh). Misalnya, saat menyalin rentang memori dengan konten tag yang tidak diketahui, atau mengatasi bottleneck performa dalam loop panas. - Saat menggunakan
M_HEAP_TAGGING_LEVEL_SYNC
, pengendali error sistem memberikan informasi tambahan seperti pelacakan tumpukan alokasi dan dealokasi. Fungsi ini memerlukan akses ke bit tag dan diaktifkan dengan meneruskan flagSA_EXPOSE_TAGBITS
saat menyetel pengendali sinyal. Setiap program yang menetapkan pengendali sinyal sendiri dan mendelegasikan error yang tidak diketahui ke sistem, sebaiknya lakukan hal yang sama.
MTE di kernel
Untuk mengaktifkan KASAN yang dipercepat MTE untuk kernel, konfigurasikan kernel dengan
CONFIG_KASAN=y
, CONFIG_KASAN_HW_TAGS=y
. Konfigurasi ini
diaktifkan secara default di 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
.
- Pengumpulan pelacakan tumpukan juga memerlukan
kasan.fault=[report|panic]
- apakah hanya akan 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 yang menggunakan variabel lingkungan atau dengan sistem build. Dalam mode ini, bug terdeteksi di awal proses pengembangan, codebase distabilkan lebih cepat, dan biaya mendeteksi bug nanti dalam produksi dapat dihindari.
Sebaiknya gunakan mode ASYNC dalam produksi. Hal ini menyediakan alat overhead rendah untuk mendeteksi keberadaan bug keamanan memori dalam proses serta pertahanan menyeluruh lebih lanjut. Setelah bug terdeteksi, developer dapat memanfaatkan API runtime untuk beralih ke mode SYNC dan mendapatkan pelacakan tumpukan yang akurat dari kumpulan sampel pengguna.
Sebaiknya konfigurasikan level MTE pilihan khusus CPU untuk SoC. Mode Asymm biasanya memiliki karakteristik performa yang sama dengan ASYNC, dan hampir selalu lebih disukai. Core in-order kecil sering kali menunjukkan performa yang serupa dalam ketiga mode, dan dapat dikonfigurasi untuk memilih SYNC.
Developer harus memeriksa keberadaan error dengan memeriksa
/data/tombstones
,
logcat
, atau dengan memantau pipeline DropboxManager
vendor untuk menemukan 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 yang penting bagi keamanan menggunakan MTE ASYNC untuk mendeteksi error pengguna akhir dan bertindak sebagai lapisan tambahan pertahanan menyeluruh. Komponen ini adalah:
- Daemon dan utilitas jaringan (kecuali
netd
) - Bluetooth, SecureElement, HAL NFC, dan aplikasi sistem
- Daemon
statsd
system_server
zygote64
(untuk mengizinkan aplikasi memilih untuk menggunakan MTE)
Target ini dipilih berdasarkan kriteria berikut:
- Proses dengan hak istimewa (didefinisikan sebagai proses yang memiliki akses ke sesuatu yang tidak dimiliki domain SELinux unprivileged_app)
- Memproses input yang tidak tepercaya (Aturan dua)
- Penurunan performa yang dapat diterima (penurunan performa tidak menyebabkan 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.
Di masa mendatang, Android berencana untuk memperluas daftar komponen sistem tempat MTE
diaktifkan, yang dipandu oleh karakteristik performa desain hardware mendatang.