Arm v9 memperkenalkan Memory Tagging Extension (MTE) Arm, implementasi hardware dari memori yang diberi tag.
Secara umum, MTE memberi tag pada setiap alokasi/dealokasi memori dengan metadata tambahan. Hal 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, pengalokasi memori heap kernel dan ruang pengguna dapat menambah setiap alokasi dengan metadata. Hal ini membantu mendeteksi bug penggunaan setelah pelepasan dan buffer overflow, yang merupakan sumber paling umum dari bug keamanan memori dalam 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 mencatat rekaman jejak stack untuk semua alokasi dan dealokasi serta menggunakannya untuk memberikan laporan error yang lebih baik yang mencakup penjelasan tentang error memori, seperti use-after-free, atau buffer overflow, dan rekaman jejak stack dari 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, prosesor akan melanjutkan eksekusi hingga
entri kernel terdekat (misalnya, syscall atau interupsi timer), yang menghentikan
proses dengan SIGSEGV
(kode SEGV_MTEAERR
) tanpa
mencatat 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 menyediakan pemeriksaan sinkron pada pembacaan memori, dan pemeriksaan asinkron pada penulisan memori, dengan performa yang mirip dengan mode ASYNC. Dalam sebagian besar situasi, mode ini lebih baik daripada mode ASYNC, dan sebaiknya gunakan mode ini daripada 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. 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 MTE-nya diaktifkan di bawah).
Mengaktifkan MTE menggunakan sistem build
Sebagai properti seluruh proses, MTE dikontrol oleh setelan waktu build dapat dieksekusi utama. Opsi berikut memungkinkan perubahan setelan ini untuk file yang dapat dieksekusi satu per satu, atau untuk seluruh subdirektori dalam struktur sumber. Setelan 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_heap LOCAL_SANITIZE_DIAG := memtag_heap |
2. Mengaktifkan MTE di subdirektori di pohon sumber menggunakan variabel produk:
Mode MTE | Sertakan 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 menyetel properti sistem berikut:
arm64.memtag.process.<basename> = (off|sync|async)
Dengan basename
adalah nama dasar file yang dapat dieksekusi.
Misalnya, untuk menyetel /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 dinonaktifkan secara default, tetapi
aplikasi yang ingin menggunakan MTE dapat melakukannya dengan menyetel 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
).
Perubahan ini dapat ditemukan di bagian System > Advanced > Developer options
> App Compatibility Changes
dalam menu setelan global. Menetapkan
NATIVE_MEMTAG_ASYNC
atau NATIVE_MEMTAG_SYNC
akan mengaktifkan MTE
untuk aplikasi tertentu.
Atau, setelan ini dapat ditetapkan menggunakan perintah 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 penyiapan. Hal ini membantu mendeteksi bug keamanan memori sejak 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 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 serupa dengan
performa ASYNC. Hal ini membuat pengaktifan pemeriksaan yang lebih ketat pada CPU tersebut menjadi berharga saat mode pemeriksaan yang kurang ketat diminta, untuk mendapatkan manfaat deteksi error dari pemeriksaan yang lebih ketat tanpa kerugian 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 di CPU tertentu, sinkronisasi nilai harus ditulis ke entri sysfs
/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 ASYNCH di mode SYNC, dan CPU 2-3 agar berjalan di mode ASYMM,
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
Penanda dari proses mode ASYNC yang berjalan dalam mode SYNC akan berisi stack trace yang tepat dari lokasi error memori. Namun, tidak akan 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_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 buffer linear dengan menetapkan nilai tag yang berbeda ke alokasi yang berdekatan. Mode ini memiliki peluang yang sedikit lebih kecil 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 butiran tag yang sama (chunk yang diselaraskan 16 byte), dan dapat melewatkan overflow kecil bahkan 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_UAF
- mengaktifkan tag yang diacak secara independen untuk probabilitas ~93% yang seragam dalam mendeteksi bug spasial (buffer overflow) dan temporal (use after free).
Selain API yang dijelaskan di atas, pengguna berpengalaman mungkin ingin mengetahui hal berikut:
- Menyetel register hardware
PSTATE.TCO
dapat menonaktifkan pemeriksaan tag untuk sementara (contoh). Misalnya, saat menyalin rentang memori dengan konten tag yang tidak diketahui, atau mengatasi hambatan performa dalam loop panas. - Saat menggunakan
M_HEAP_TAGGING_LEVEL_SYNC
, handler error sistem memberikan informasi tambahan seperti rekaman aktivitas alokasi dan dealokasi. Fungsi ini memerlukan akses ke bit tag dan diaktifkan dengan meneruskan flagSA_EXPOSE_TAGBITS
saat menyetel handler sinyal. Program apa pun yang menyetel handler sinyalnya sendiri dan mendelegasikan error yang tidak diketahui ke sistem direkomendasikan untuk 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
.
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]
- pilih antara mode sinkron dan asinkron (default:sync
)kasan.stacktrace=[on|off]
- apakah akan mengumpulkan stack trace (default:on
)- pengumpulan rekaman aktivitas stack juga memerlukan
stack_depot_disable=off
.
- pengumpulan rekaman aktivitas stack juga memerlukan
kasan.fault=[report|panic]
- apakah hanya mencetak laporan, atau juga menyebabkan 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 pendeteksian bug di kemudian hari dalam produksi dapat dihindari.
Sebaiknya gunakan mode ASYNC dalam produksi. Hal ini memberikan 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 sekumpulan pengguna yang disampel.
Sebaiknya konfigurasi tingkat MTE pilihan khusus CPU untuk SoC. Mode asimetris biasanya memiliki karakteristik performa yang sama dengan ASYNC, dan hampir selalu lebih disukai. Inti dalam urutan kecil sering 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 mengetahui bug pengguna akhir. Untuk mengetahui info selengkapnya tentang proses debug kode native Android, lihat
informasi di sini.
Komponen platform yang mendukung MTE
Di Android 12, sejumlah komponen sistem penting keamanan menggunakan MTE ASYNC untuk mendeteksi error pengguna akhir dan bertindak sebagai lapisan tambahan pertahanan mendalam. 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 istimewa (didefinisikan sebagai proses yang memiliki akses ke sesuatu yang tidak dimiliki oleh domain SELinux unprivileged_app)
- Memproses input yang tidak tepercaya (Aturan dua)
- Perlambatan performa yang dapat diterima (perlambatan tidak menyebabkan latensi yang terlihat oleh pengguna)
Kami mendorong vendor untuk 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.
Pada masa mendatang, Android berencana memperluas daftar komponen sistem yang mengaktifkan MTE, yang dipandu oleh karakteristik performa desain hardware mendatang.