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
untuk sementara dapat 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 stack trace alokasi dan dealokasi. Fungsi ini memerlukan akses ke bit tag dan diaktifkan dengan meneruskanSA_EXPOSE_TAGBITS
penanda saat mengatur pengendali sinyal. Setiap 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
.
- pengumpulan pelacakan tumpukan juga memerlukan
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.
Penggunaan yang direkomendasikan
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 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.