Integritas Aliran Kontrol

Pada tahun 2016, sekitar 86% dari semua kerentanan di Android terkait dengan keamanan memori. Sebagian besar kerentanan dieksploitasi oleh penyerang yang mengubah aliran kontrol normal aplikasi untuk melakukan aktivitas berbahaya secara sewenang-wenang dengan semua hak istimewa aplikasi yang dieksploitasi. Integritas aliran kontrol (CFI) adalah mekanisme keamanan yang melarang perubahan pada grafik aliran kontrol asli dari biner yang dikompilasi, sehingga sangat sulit untuk melakukan serangan semacam itu.

Di Android 8.1, kami mengaktifkan implementasi CFI LLVM di tumpukan media. Di Android 9, kami mengaktifkan CFI di lebih banyak komponen dan juga kernel. Keuangan Sistem diaktifkan secara default tetapi Anda harus mengaktifkan Keuangan Kernel.

Keuangan LLVM memerlukan kompilasi dengan Link-Time Optimization (LTO) . LTO mempertahankan representasi bitcode LLVM dari file objek hingga waktu tautan, yang memungkinkan kompiler untuk memberikan alasan yang lebih baik tentang pengoptimalan apa yang dapat dilakukan. Mengaktifkan LTO mengurangi ukuran biner akhir dan meningkatkan kinerja, namun meningkatkan waktu kompilasi. Dalam pengujian di Android, kombinasi LTO dan Keuangan menghasilkan overhead yang dapat diabaikan terhadap ukuran dan kinerja kode; dalam beberapa kasus keduanya membaik.

Untuk detail teknis lebih lanjut tentang Keuangan dan cara penanganan pemeriksaan kontrol maju lainnya, lihat dokumentasi desain LLVM .

Contoh dan sumber

CFI disediakan oleh kompiler dan menambahkan instrumentasi ke dalam biner selama waktu kompilasi. Kami mendukung Keuangan di toolchain Clang dan sistem build Android di AOSP.

CFI diaktifkan secara default untuk perangkat Arm64 untuk kumpulan komponen di /platform/build/target/product/cfi-common.mk . Ini juga diaktifkan secara langsung di kumpulan file makefile/cetak biru komponen media, seperti /platform/frameworks/av/media/libmedia/Android.bp dan /platform/frameworks/av/cmds/stagefright/Android.mk .

Menerapkan sistem Keuangan

Keuangan diaktifkan secara default jika Anda menggunakan Dentang dan sistem build Android. Karena CFI membantu menjaga keamanan pengguna Android, Anda tidak boleh menonaktifkannya.

Faktanya, kami sangat menganjurkan Anda untuk mengaktifkan CFI untuk komponen tambahan. Kandidat yang ideal adalah kode asli yang memiliki hak istimewa, atau kode asli yang memproses masukan pengguna yang tidak tepercaya. Jika Anda menggunakan clang dan sistem build Android, Anda dapat mengaktifkan CFI di komponen baru dengan menambahkan beberapa baris ke file makefile atau cetak biru Anda.

Mendukung Keuangan di makefiles

Untuk mengaktifkan CFI di file make, seperti /platform/frameworks/av/cmds/stagefright/Android.mk , tambahkan:

LOCAL_SANITIZE := cfi
# Optional features
LOCAL_SANITIZE_DIAG := cfi
LOCAL_SANITIZE_BLACKLIST := cfi_blacklist.txt
  • LOCAL_SANITIZE menetapkan CFI sebagai pembersih selama pembuatan.
  • LOCAL_SANITIZE_DIAG mengaktifkan mode diagnostik untuk Keuangan. Mode diagnostik mencetak informasi debug tambahan di logcat selama error, yang berguna saat mengembangkan dan menguji build Anda. Namun, pastikan untuk menghapus mode diagnostik pada build produksi.
  • LOCAL_SANITIZE_BLACKLIST memungkinkan komponen menonaktifkan instrumentasi Keuangan secara selektif untuk masing-masing fungsi atau file sumber. Anda dapat menggunakan daftar hitam sebagai upaya terakhir untuk memperbaiki masalah apa pun yang dihadapi pengguna yang mungkin ada. Untuk detail lebih lanjut, lihat Menonaktifkan Keuangan .

Mendukung Keuangan dalam file cetak biru

Untuk mengaktifkan CFI dalam file cetak biru, seperti /platform/frameworks/av/media/libmedia/Android.bp , tambahkan:

   sanitize: {
        cfi: true,
        diag: {
            cfi: true,
        },
        blacklist: "cfi_blacklist.txt",
    },

Penyelesaian masalah

Jika Anda mengaktifkan CFI di komponen baru, Anda mungkin mengalami beberapa masalah dengan kesalahan ketidakcocokan jenis fungsi dan kesalahan ketidakcocokan jenis kode perakitan .

Kesalahan ketidakcocokan tipe fungsi terjadi karena CFI membatasi panggilan tidak langsung untuk hanya beralih ke fungsi yang memiliki tipe dinamis yang sama dengan tipe statis yang digunakan dalam panggilan. CFI membatasi panggilan fungsi anggota virtual dan non-virtual untuk hanya melompat ke objek yang merupakan kelas turunan dari tipe statis objek yang digunakan untuk melakukan panggilan. Artinya, jika Anda memiliki kode yang melanggar salah satu asumsi ini, instrumentasi yang ditambahkan CFI akan dibatalkan. Misalnya, pelacakan tumpukan memperlihatkan SIGABRT dan logcat berisi baris tentang integritas aliran kontrol yang menemukan ketidakcocokan.

Untuk memperbaikinya, pastikan fungsi yang dipanggil memiliki tipe yang sama dengan yang dideklarasikan secara statis. Berikut adalah dua contoh CL:

Masalah lain yang mungkin terjadi adalah mencoba mengaktifkan CFI dalam kode yang berisi panggilan tidak langsung ke Majelis. Karena kode perakitan tidak diketik, hal ini mengakibatkan ketidakcocokan tipe.

Untuk memperbaikinya, buat pembungkus kode asli untuk setiap panggilan Majelis, dan berikan pembungkus tersebut tanda tangan fungsi yang sama dengan penunjuk panggilan. Pembungkus kemudian dapat langsung memanggil kode perakitan. Karena cabang langsung tidak diinstrumentasi oleh CFI (cabang tersebut tidak dapat diarahkan ulang saat runtime sehingga tidak menimbulkan risiko keamanan), hal ini akan mengatasi masalah tersebut.

Jika ada terlalu banyak fungsi rakitan dan semuanya tidak dapat diperbaiki, Anda juga dapat memasukkan semua fungsi yang berisi panggilan tidak langsung ke rakitan ke dalam daftar hitam. Hal ini tidak disarankan karena menonaktifkan pemeriksaan CFI pada fungsi-fungsi ini, sehingga membuka permukaan serangan.

Menonaktifkan Keuangan

Kami tidak melihat adanya overhead kinerja, jadi Anda tidak perlu menonaktifkan Keuangan. Namun, jika ada dampak yang dihadapi pengguna, Anda dapat menonaktifkan CFI secara selektif untuk masing-masing fungsi atau file sumber dengan menyediakan file daftar hitam pembersih pada waktu kompilasi. Daftar hitam memerintahkan kompiler untuk menonaktifkan instrumentasi Keuangan di lokasi tertentu.

Sistem build Android menyediakan dukungan untuk daftar hitam per komponen (memungkinkan Anda memilih file sumber atau fungsi individual yang tidak akan menerima instrumentasi CFI) untuk Make dan Soong. Untuk detail lebih lanjut tentang format file daftar hitam, lihat dokumen Clang upstream .

Validasi

Saat ini belum ada tes CTS khusus untuk Keuangan. Sebaliknya, pastikan pengujian CTS lulus dengan atau tanpa CFI diaktifkan untuk memverifikasi bahwa CFI tidak memengaruhi perangkat.