Ekstensi Penandaan Memori Lengan

Arm v9 memperkenalkan Arm Memory Tagging Extension (MTE), implementasi perangkat keras dari memori yang diberi tag.

Pada tingkat tinggi, MTE menandai setiap alokasi/dealokasi memori dengan metadata tambahan. Ini memberikan tag ke lokasi memori, yang kemudian dapat dikaitkan dengan pointer yang mereferensikan lokasi memori itu. Saat runtime, CPU memeriksa apakah penunjuk 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. Ini membantu mendeteksi bug penggunaan-setelah-bebas dan buffer-overflow, yang merupakan sumber paling umum dari bug keamanan memori di basis kode 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 kinerja dan dapat digunakan sebagai alat deteksi bug yang tepat, ketika overhead kinerja yang lebih tinggi dapat diterima. Saat diaktifkan, MTE SYNC bertindak sebagai mitigasi keamanan. Pada ketidakcocokan tag, prosesor segera membatalkan eksekusi dan menghentikan proses dengan SIGSEGV (kode SEGV_MTESERR ) dan informasi lengkap tentang akses memori dan alamat kesalahan.

Kami merekomendasikan penggunaan mode ini selama pengujian sebagai alternatif untuk HWASan/KASAN atau dalam produksi ketika proses target mewakili permukaan serangan yang rentan. Selain itu, ketika mode ASYNC 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 pelacakan tumpukan untuk semua alokasi dan dealokasi dan menggunakannya untuk memberikan laporan kesalahan yang lebih baik yang menyertakan penjelasan tentang kesalahan memori, seperti penggunaan-setelah-bebas, atau buffer-overflow, dan tumpukan jejak peristiwa memori yang relevan. Laporan semacam itu memberikan lebih banyak informasi kontekstual dan membuat bug lebih mudah dilacak dan diperbaiki.

Mode asinkron (ASYNC)

Mode ini dioptimalkan untuk kinerja di atas akurasi laporan bug dan dapat digunakan sebagai deteksi overhead rendah untuk bug keamanan memori.
Pada ketidakcocokan tag, prosesor melanjutkan eksekusi hingga entri kernel terdekat (misalnya, interupsi syscall atau timer), di mana prosesor menghentikan proses dengan SIGSEGV (kode SEGV_MTEAERR ) tanpa merekam alamat yang salah atau akses memori.
Kami merekomendasikan penggunaan mode ini dalam produksi pada basis kode yang teruji 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 Asymmetric MTE menyediakan pemeriksaan sinkron pada pembacaan memori, dan pemeriksaan asinkron penulisan memori, dengan kinerja yang serupa dengan mode ASYNC. Dalam kebanyakan situasi, mode ini merupakan peningkatan dari mode ASYNC, dan kami menyarankan untuk menggunakannya daripada ASYNC kapan pun tersedia.

Karena alasan ini, tidak ada API yang dijelaskan di bawah yang menyebutkan mode Asimetris. Sebagai gantinya, OS dapat dikonfigurasi untuk selalu menggunakan mode Asimetris saat Asynchronous diminta. Silakan merujuk ke bagian "Mengonfigurasi level MTE pilihan khusus CPU" untuk informasi lebih lanjut.

MTE di ruang pengguna

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

Mengaktifkan MTE menggunakan sistem build

Sebagai properti seluruh proses, MTE dikendalikan oleh pengaturan waktu pembuatan dari executable utama. Opsi berikut memungkinkan mengubah pengaturan ini untuk masing-masing executable, atau untuk seluruh subdirektori di pohon sumber. Pengaturan diabaikan di perpustakaan, atau target apa pun yang tidak dapat dieksekusi atau diuji.

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

Modus MTE Pengaturan
MTE asinkron
  sanitize: {
  memtag_heap: true,
  }
MTE sinkron
  sanitize: {
  memtag_heap: true,
  diag: {
  memtag_heap: true,
  },
  }

atau di Android.mk:

Modus MTE Pengaturan
Asynchronous MTE LOCAL_SANITIZE := memtag_heap
Synchronous MTE LOCAL_SANITIZE := memtag_heap
LOCAL_SANITIZE_DIAG := memtag_heap

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

Modus MTE Sertakan daftar Kecualikan daftar
tidak sinkron PRODUCT_MEMTAG_HEAP_ASYNC_INCLUDE_PATHS MEMTAG_HEAP_ASYNC_INCLUDE_PATHS PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
sinkronisasi PRODUCT_MEMTAG_HEAP_SYNC_INCLUDE_PATHS MEMTAG_HEAP_SYNC_INCLUDE_PATHS

atau

Modus MTE Pengaturan
MTE asinkron MEMTAG_HEAP_ASYNC_INCLUDE_PATHS
MTE sinkron MEMTAG_HEAP_SYNC_INCLUDE_PATHS

atau dengan menentukan jalur pengecualian dari executable:

Modus MTE Pengaturan
MTE asinkron PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
MTE sinkron

Contoh, (penggunaan serupa dengan PRODUCT_CFI_INCLUDE_PATHS )

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

Mengaktifkan MTE menggunakan properti sistem

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

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

Di mana basename adalah nama dasar dari executable.

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

Satu cara lagi untuk mengganti pengaturan build adalah dengan mendefinisikan variabel lingkungan: MEMTAG_OPTIONS=(off|sync|async) Jika variabel lingkungan dan properti sistem ditentukan, variabel akan diutamakan.

Mengaktifkan MTE untuk aplikasi

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

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

Saat disetel pada tag <application> , atribut tersebut memengaruhi semua proses yang digunakan oleh aplikasi, dan dapat ditimpa untuk proses individual dengan menyetel tag <process> .

Untuk eksperimen, perubahan kompatibilitas dapat digunakan untuk menyetel nilai default atribut memtagMode untuk aplikasi yang tidak menentukan nilai apa pun dalam manifes (atau menetapkan default ).
Ini dapat ditemukan di bawah System > Advanced > Developer options > App Compatibility Changes di menu pengaturan global. Menyetel NATIVE_MEMTAG_ASYNC atau NATIVE_MEMTAG_SYNC mengaktifkan MTE untuk aplikasi tertentu.
Atau, ini dapat diatur menggunakan perintah am sebagai berikut:

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

Membangun citra sistem MTE

Kami sangat menyarankan untuk mengaktifkan MTE di semua binari asli selama pengembangan dan pengembangan. Ini membantu mendeteksi bug keamanan memori lebih awal dan memberikan cakupan pengguna yang realistis, jika diaktifkan dalam pengujian build.

Kami sangat menyarankan untuk mengaktifkan MTE dalam mode Sinkron pada semua binari asli selama pengembangan

SANITIZE_TARGET=memtag_heap SANITIZE_TARGET_DIAG=memtag_heap m

Seperti halnya variabel apa pun dalam sistem pembangunan, SANITIZE_TARGET dapat digunakan sebagai variabel lingkungan atau pengaturan make (misalnya, dalam file product.mk ).
Harap dicatat bahwa ini mengaktifkan MTE untuk semua proses asli, tetapi tidak untuk aplikasi (yang bercabang dari zygote64 ) yang MTE dapat diaktifkan dengan mengikuti petunjuk di atas .

Mengonfigurasi level MTE pilihan khusus CPU

Pada beberapa CPU, kinerja MTE dalam mode ASYMM atau bahkan SYNC mungkin mirip dengan ASYNC. Ini membuatnya bermanfaat untuk mengaktifkan pemeriksaan yang lebih ketat pada CPU tersebut ketika mode pemeriksaan yang kurang ketat diminta, untuk mendapatkan manfaat deteksi kesalahan dari pemeriksaan yang lebih ketat tanpa kerugian kinerja.
Secara default, proses yang dikonfigurasi untuk berjalan dalam mode ASYNC akan berjalan dalam mode ASYNC di semua CPU. Untuk mengkonfigurasi 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 saat boot. Ini dapat dilakukan dengan skrip init. Misalnya, untuk mengonfigurasi CPU 0-1 untuk menjalankan proses mode ASYNC dalam mode SYNC, dan CPU 2-3 untuk menjalankan mode ASYMM, berikut ini 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

Batu nisan dari proses mode ASYNC yang berjalan dalam mode SYNC akan berisi jejak tumpukan yang tepat dari lokasi kesalahan memori. Namun, mereka tidak akan menyertakan pelacakan tumpukan alokasi atau dealokasi. Jejak tumpukan ini hanya tersedia jika proses dikonfigurasi untuk berjalan dalam mode SYNC.

int mallopt(M_THREAD_DISABLE_MEM_INIT, level)

dimana level 0 atau 1.
Menonaktifkan inisialisasi memori di malloc, dan menghindari perubahan tag memori kecuali diperlukan untuk kebenaran.

int mallopt(M_MEMTAG_TUNING, level)

dimana level adalah:

  • M_MEMTAG_TUNING_BUFFER_OVERFLOW
  • M_MEMTAG_TUNING_UAF

Memilih strategi alokasi tag.

  • Setelan defaultnya adalah M_MEMTAG_TUNING_BUFFER_OVERFLOW .
  • M_MEMTAG_TUNING_BUFFER_OVERFLOW - memungkinkan deteksi deterministik bug buffer overflow dan underflow linier dengan menetapkan nilai tag yang berbeda ke alokasi yang berdekatan. Mode ini memiliki peluang yang sedikit berkurang untuk mendeteksi bug penggunaan setelah bebas karena hanya setengah dari kemungkinan nilai tag yang tersedia untuk setiap lokasi memori. Harap diingat bahwa MTE tidak dapat mendeteksi luapan di dalam butiran tag yang sama (potongan selaras 16 byte), dan dapat melewatkan luapan kecil bahkan dalam mode ini. Overflow seperti itu tidak dapat menjadi penyebab kerusakan memori, karena memori dalam satu granul tidak pernah digunakan untuk beberapa alokasi.
  • M_MEMTAG_TUNING_UAF - mengaktifkan tag acak independen untuk kemungkinan ~93% yang seragam dalam mendeteksi bug spasial (buffer overflow) dan temporal (digunakan setelah gratis).

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

  • Menyetel register perangkat keras PSTATE.TCO dapat sementara menekan pemeriksaan tag ( contoh ). Misalnya, saat menyalin rentang memori dengan konten tag yang tidak diketahui, atau mengatasi hambatan kinerja dalam loop panas.
  • Saat menggunakan M_HEAP_TAGGING_LEVEL_SYNC , pengendali kerusakan sistem memberikan informasi tambahan seperti pelacakan tumpukan alokasi dan dealokasi. Fungsionalitas ini memerlukan akses ke bit tag dan diaktifkan dengan meneruskan flag SA_EXPOSE_TAGBITS saat menyetel pengendali sinyal. Program apa pun yang mengatur penangan sinyalnya sendiri dan mendelegasikan kerusakan yang tidak diketahui ke sistem, disarankan untuk melakukan 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 pada kernel GKI, dimulai dengan Android 12-5.10 .
Ini dapat dikontrol saat boot menggunakan argumen baris perintah berikut:

  • kasan=[on|off] - aktifkan atau nonaktifkan KASAN (default: on )
  • kasan.mode=[sync |async ] - pilih antara mode sinkron dan asinkron (default: sync )
  • kasan.stacktrace=[on|off] - apakah akan mengumpulkan jejak tumpukan (default: on )
    • pengumpulan jejak tumpukan juga membutuhkan stack_depot_disable=off .
  • kasan.fault=[report|panic] - apakah hanya mencetak laporan, atau juga membuat panik kernel (default: report ). Terlepas dari opsi ini, pemeriksaan tag akan dinonaktifkan setelah kesalahan pertama yang dilaporkan.

Kami sangat menyarankan untuk menggunakan mode SYNC selama pembukaan, pengembangan, dan pengujian. Opsi ini harus diaktifkan secara global untuk semua proses yang menggunakan variabel lingkungan atau dengan sistem pembangunan . Dalam mode ini, bug terdeteksi di awal proses pengembangan, basis kode distabilkan lebih cepat dan biaya mendeteksi bug di kemudian hari dalam produksi dapat dihindari.

Kami sangat menyarankan menggunakan mode ASYNC dalam produksi. Ini menyediakan alat overhead rendah untuk mendeteksi keberadaan bug keamanan memori dalam suatu proses serta pertahanan lebih mendalam. Setelah bug terdeteksi, pengembang dapat memanfaatkan API runtime untuk beralih ke mode SYNC dan mendapatkan pelacakan tumpukan yang akurat dari kumpulan pengguna yang dijadikan sampel.

Kami sangat menyarankan untuk mengonfigurasi level MTE pilihan khusus CPU untuk SoC. Mode Asymm biasanya memiliki karakteristik kinerja yang sama dengan ASYNC, dan hampir selalu lebih disukai daripada itu. Core kecil dalam urutan sering menunjukkan kinerja yang sama di ketiga mode, dan dapat dikonfigurasi untuk memilih SYNC.

Pengembang harus memeriksa adanya kerusakan dengan memeriksa /data/tombstones , logcat atau dengan memantau pipa vendor DropboxManager untuk bug pengguna akhir. Untuk info selengkapnya tentang men-debug kode asli Android, lihat informasinya di sini .

Komponen platform berkemampuan MTE

Di Android 12, sejumlah komponen sistem kritis keamanan menggunakan MTE ASYNC untuk mendeteksi kerusakan pengguna akhir dan bertindak sebagai lapisan pertahanan tambahan yang mendalam. Komponen-komponen ini adalah:

  • Daemon dan utilitas jaringan (dengan pengecualian netd )
  • Bluetooth, SecureElement, NFC HAL, dan aplikasi sistem
  • statsd daemon
  • system_server
  • zygote64 (untuk mengizinkan aplikasi ikut serta menggunakan MTE)

Target ini dipilih berdasarkan kriteria berikut:

  • Proses istimewa (didefinisikan sebagai proses yang memiliki akses ke sesuatu yang tidak dimiliki domain SELinux unprivileged_app)
  • Memproses input yang tidak dapat dipercaya ( Aturan dua )
  • Perlambatan kinerja yang dapat diterima (perlambatan tidak membuat latensi yang terlihat oleh pengguna)

Kami mendorong vendor untuk mengaktifkan MTE dalam produksi untuk lebih banyak komponen, mengikuti kriteria yang disebutkan di atas. Selama pengembangan, kami merekomendasikan pengujian komponen ini menggunakan mode SYNC, untuk mendeteksi bug yang diperbaiki dengan mudah, dan menilai dampak ASYNC pada kinerjanya.
Di masa depan, Android berencana untuk memperluas daftar komponen sistem yang diaktifkan MTE, dipandu oleh karakteristik kinerja desain perangkat keras yang akan datang.