Bagian kode yang dapat dieksekusi untuk biner sistem AArch64 ditandai secara default eksekusi-saja (tidak dapat dibaca) sebagai mitigasi pengerasan terhadap kode tepat waktu serangan {i>restart<i}. Kode yang mencampur data dan kode bersama-sama dan membuat kode yang sengaja memeriksa bagian ini (tanpa terlebih dahulu memetakan ulang segmen memori sebagai dapat dibaca) tidak lagi berfungsi. Aplikasi dengan SDK target 10 (API level 29 atau yang lebih tinggi) akan terpengaruh jika aplikasi mencoba membaca bagian kode dari {i>Execute-only memory<i} (XOM) yang mengaktifkan library sistem di memori tanpa terlebih dahulu menandai bagian tersebut sebagai dapat dibaca.
Untuk memanfaatkan sepenuhnya mitigasi ini, dukungan perangkat keras dan {i>kernel<i} tidak diperlukan. Tanpa dukungan ini, mitigasi mungkin hanya diterapkan sebagian. Tujuan Kernel umum Android 4.9 berisi patch yang sesuai untuk menyediakan dukungan untuk ini di perangkat ARMv8.2.
Implementasi
Biner AArch64 yang dihasilkan oleh compiler menganggap bahwa kode dan data tidak bercampur. Mengaktifkan fitur ini tidak berdampak negatif terhadap performa perangkat.
Untuk kode yang harus melakukan introspeksi memori yang disengaja pada
segmen yang dapat dieksekusi, sebaiknya panggil mprotect
di
segmen kode yang membutuhkan pemeriksaan
agar bisa dibaca, maka
menghilangkan keterbacaan saat pemeriksaan selesai.
Implementasi ini menyebabkan pembacaan ke segmen memori yang ditandai sebagai
jalankan saja untuk menghasilkan kesalahan segmentasi (SEGFAULT
).
Hal ini dapat terjadi sebagai akibat dari {i>bug<i}, kerentanan, data yang tercampur dengan
kode (penggabungan literal), atau introspeksi memori yang disengaja.
Dampak dan dukungan perangkat
Perangkat dengan perangkat keras yang lebih lawas atau kernel yang lebih lawas (lebih rendah dari 4,9) tanpa
{i>patch<i} yang diperlukan mungkin tidak sepenuhnya
mendukung atau memanfaatkan fitur ini. Perangkat
tanpa dukungan {i>kernel<i} tidak dapat memberlakukan
akses pengguna ke memori {i>execute-only<i},
Namun, kode {i>kernel<i} yang secara eksplisit memeriksa apakah
suatu laman dapat dibaca mungkin
menerapkan properti ini, seperti process_vm_readv()
.
Flag kernel CONFIG_ARM64_UAO
harus ditetapkan dalam kernel agar
memastikan bahwa {i>kernel<i} mengikuti laman
pengguna yang ditandai sebagai {i>execute-only<i}. ARMv8 sebelumnya
perangkat ARMv8.2 dengan User Access Override (UAO) nonaktif, mungkin tidak
memanfaatkan sepenuhnya fungsi ini dan mungkin masih dapat
membaca laman khusus eksekusi dengan menggunakan
{i>syscall<i}.
Memfaktorkan ulang kode yang ada
Kode yang telah ditransfer dari AArch32
mungkin berisi data campuran dan
kode tertentu, yang menyebabkan munculnya masalah. Dalam banyak kasus, memperbaiki
masalah ini semudah
sebagai memindahkan konstanta ke bagian .data
dalam file assembly.
Rakitan tulisan tangan mungkin perlu difaktorkan ulang untuk memisahkan penggabungan secara lokal konstanta.
Contoh:
Biner yang dihasilkan oleh compiler Clang seharusnya tidak memiliki masalah data dicampur dalam kode. Jika kode yang dihasilkan GNU compiler collection (GCC) adalah disertakan (dari {i>library<i} statis), memeriksa biner {i>output<i} untuk memastikan bahwa konstanta belum dikumpulkan ke dalam bagian kode.
Jika introspeksi kode diperlukan
pada bagian kode yang dapat dieksekusi,
panggil mprotect
untuk menandai kode sebagai dapat dibaca. Kemudian setelah operasi
selesai, panggil mprotect
lagi untuk menandainya sebagai tidak dapat dibaca.
Aktifkan XOM
Hanya jalankan diaktifkan secara default untuk semua biner 64-bit dalam build sistem file.
Nonaktifkan XOM
Anda dapat menonaktifkan execution-only di level modul, oleh seluruh hierarki subdirektori, atau secara global untuk seluruh build.
XOM dapat dinonaktifkan untuk modul individu yang tidak dapat difaktorkan ulang, atau perlu membaca
kode yang dapat dieksekusi, dengan menyetel LOCAL_XOM
dan xom
variabel ke false
.
// Android.mk LOCAL_XOM := false // Android.bp cc_binary { // or other module types ... xom: false, }
Jika memori khusus eksekusi dinonaktifkan di library statis, sistem build akan menerapkan
ini untuk semua modul dependen
dari {i>library<i} statis itu. Anda dapat mengganti
ini menggunakan xom: true,
.
Untuk menonaktifkan memori execution-only di subdirektori tertentu (misalnya,
foo/bar/), teruskan nilai ke XOM_EXCLUDE_PATHS
.
make -j XOM_EXCLUDE_PATHS=foo/bar
Atau, Anda dapat menetapkan PRODUCT_XOM_EXCLUDE_PATHS
variabel dalam konfigurasi produk Anda.
Anda dapat menonaktifkan biner khusus eksekusi secara global dengan meneruskan
ENABLE_XOM=false
ke perintah make
.
make -j ENABLE_XOM=false
Validasi
Tidak ada pengujian CTS atau verifikasi yang tersedia untuk dijalankan saja
memori. Anda dapat memverifikasi biner secara manual menggunakan readelf
dan memeriksanya
penanda segmen.