SELinux disiapkan untuk menolak secara default, yang berarti setiap akses yang memiliki hook di kernel harus diizinkan secara eksplisit oleh kebijakan. Artinya, file kebijakan terdiri dari sejumlah besar informasi mengenai aturan, jenis, class, izin, dan lainnya. Pertimbangan penuh terhadap SELinux berada di luar cakupan dokumen ini, tetapi pemahaman tentang cara menulis aturan kebijakan kini penting saat mengaktifkan perangkat Android baru. Sudah ada banyak informasi yang tersedia terkait SELinux. Lihat Dokumentasi pendukung untuk mengetahui referensi yang disarankan.
File kunci
Untuk mengaktifkan SELinux, integrasikan kernel Android terbaru, lalu gabungkan file yang ditemukan di direktori system/sepolicy. Saat dikompilasi, file tersebut membentuk kebijakan keamanan kernel SELinux dan mencakup sistem operasi Android upstream.
Secara umum, Anda tidak boleh mengubah file system/sepolicy secara langsung. Sebagai gantinya, tambahkan atau edit file kebijakan khusus perangkat Anda sendiri di direktori
/device/manufacturer/device-name/sepolicy. Di Android 8.0 dan yang lebih tinggi, perubahan yang Anda buat pada file ini hanya akan memengaruhi kebijakan di direktori vendor Anda. Untuk mengetahui detail selengkapnya tentang pemisahan
sepolicy publik di Android 8.0 dan yang lebih tinggi, lihat
Menyesuaikan SEPolicy di Android
8.0+. Terlepas dari versi Android, Anda tetap memodifikasi file ini:
File kebijakan
File yang diakhiri dengan *.te adalah file sumber kebijakan SELinux, yang
menentukan domain dan labelnya. Anda mungkin perlu membuat file kebijakan baru di
/device/manufacturer/device-name/sepolicy,
tetapi Anda harus mencoba memperbarui file yang ada jika memungkinkan.
File konteks
File konteks adalah tempat Anda menentukan label untuk objek.
file_contextsmenetapkan label ke file dan digunakan oleh berbagai komponen ruang pengguna. Saat Anda membuat kebijakan baru, buat atau perbarui file ini untuk menetapkan label baru ke file. Untuk menerapkanfile_contextsbaru, bangun ulang image sistem file atau jalankanrestoreconpada file yang akan diberi label ulang. Saat upgrade, perubahan padafile_contextsakan diterapkan secara otomatis ke partisi sistem dan userdata sebagai bagian dari upgrade. Perubahan juga dapat diterapkan secara otomatis saat mengupgrade ke partisi lain dengan menambahkan panggilanrestorecon_recursiveke file init.board.rc setelah partisi dipasang baca-tulis.genfs_contextsmenetapkan label ke sistem file, sepertiprocatauvfatyang tidak mendukung atribut yang diperluas. Konfigurasi ini dimuat sebagai bagian dari kebijakan kernel, tetapi perubahan mungkin tidak diterapkan untuk inode dalam inti, sehingga memerlukan reboot atau melepas dan memasang ulang sistem file untuk menerapkan perubahan sepenuhnya. Label tertentu juga dapat ditetapkan ke pemasangan tertentu, sepertivfatmenggunakan opsicontext=mount.property_contextsmenetapkan label ke properti sistem Android untuk mengontrol proses apa yang dapat menyetelnya. Konfigurasi ini dibaca oleh prosesinitselama startup.service_contextsmenetapkan label ke layanan binder Android untuk mengontrol proses apa yang dapat menambahkan (mendaftarkan) dan menemukan (mencari) referensi binder untuk layanan. Konfigurasi ini dibaca oleh prosesservicemanagerselama startup.seapp_contextsmenetapkan label ke proses aplikasi dan direktori/data/data. Konfigurasi ini dibaca oleh proseszygotepada setiap peluncuran aplikasi dan olehinstalldselama startup.mac_permissions.xmlmenetapkan tagseinfoke aplikasi berdasarkan tanda tangan dan opsional nama paketnya. Tagseinfokemudian dapat digunakan sebagai kunci dalam fileseapp_contextsuntuk menetapkan label tertentu ke semua aplikasi dengan tagseinfotersebut. Konfigurasi ini dibaca olehsystem_serverselama startup.keystore2_key_contextsmenetapkan label ke namespace Keystore 2. Namespace ini diterapkan oleh daemonkeystore2. Keystore selalu menyediakan namespace berbasis UID/AID. Keystore 2 juga menerapkan namespace yang ditentukan sepolicy. Deskripsi mendetail tentang format dan konvensi file ini dapat ditemukan di sini.
Makefile BoardConfig.mk
Setelah mengedit atau menambahkan file kebijakan dan konteks, perbarui
makefile /device/manufacturer/device-name/BoardConfig.mk
untuk mereferensikan subdirektori sepolicy dan setiap file kebijakan baru.
Untuk mengetahui informasi selengkapnya tentang variabel BOARD_SEPOLICY, lihat
file system/sepolicy/README.
BOARD_SEPOLICY_DIRS += \
<root>/device/manufacturer/device-name/sepolicy
BOARD_SEPOLICY_UNION += \
genfs_contexts \
file_contexts \
sepolicy.te
Setelah dibangun ulang, perangkat Anda akan diaktifkan dengan SELinux. Anda kini dapat menyesuaikan kebijakan SELinux untuk mengakomodasi penambahan Anda sendiri ke sistem operasi Android seperti yang dijelaskan dalam Penyesuaian atau memverifikasi penyiapan yang ada seperti yang dibahas dalam Validasi.
Setelah file kebijakan baru dan update BoardConfig.mk diterapkan, setelan kebijakan baru akan otomatis dibuat ke dalam file kebijakan kernel akhir. Untuk mengetahui informasi selengkapnya tentang cara sepolicy dibangun di perangkat, lihat Membangun sepolicy.
Implementasi
Untuk mulai menggunakan SELinux:
- Aktifkan SELinux di kernel:
CONFIG_SECURITY_SELINUX=y - Ubah parameter kernel_cmdline atau bootconfig sehingga:
atauBOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
Opsi ini hanya untuk pengembangan awal kebijakan untuk perangkat. Setelah Anda memiliki kebijakan bootstrap awal, hapus parameter ini agar perangkat Anda menerapkan atau gagal CTS.BOARD_BOOTCONFIG := androidboot.selinux=permissive
- Booting sistem dalam mode permisif dan lihat penolakan yang terjadi saat booting:
Di Ubuntu 14.04 atau yang lebih baru: Di Ubuntu 12.04:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- Evaluasi output untuk melihat peringatan yang menyerupai
init: Warning! Service name needs a SELinux domain defined; please fix!Lihat Validasi untuk mengetahui petunjuk dan alat. - Identifikasi perangkat, dan file baru lainnya yang perlu diberi label.
- Gunakan label yang ada atau baru untuk objek Anda. Lihat file
*_contextsuntuk melihat cara pelabelan sebelumnya dan gunakan pengetahuan tentang arti label untuk menetapkan label baru. Idealnya, ini adalah label yang sudah ada dan sesuai dengan kebijakan, tetapi terkadang label baru diperlukan, dan aturan untuk akses ke label tersebut diperlukan. Tambahkan label Anda ke file konteks yang sesuai. - Identifikasi domain/proses yang harus memiliki domain keamanannya sendiri.
Anda mungkin perlu menulis kebijakan yang benar-benar baru untuk masing-masingnya. Semua
layanan yang dihasilkan dari
init, misalnya, harus memiliki layanan mereka sendiri. Perintah berikut membantu mengungkapkan layanan yang masih berjalan (tetapi SEMUA layanan memerlukan penanganan tersebut):
adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
- Tinjau
init.device.rcuntuk mengidentifikasi domain yang tidak memiliki jenis domain. Berikan domain kepada mereka di awal proses pengembangan Anda untuk menghindari penambahan aturan keinitatau mengacaukan aksesinitdengan akses yang ada dalam kebijakan mereka sendiri. - Siapkan
BOARD_CONFIG.mkuntuk menggunakan variabelBOARD_SEPOLICY_*. Lihat README disystem/sepolicyuntuk mengetahui detail tentang cara menyiapkannya. - Periksa file init.device.rc dan fstab.device, lalu
pastikan setiap penggunaan
mountsesuai dengan sistem file yang diberi label dengan benar atau opsicontext= mountditentukan. - Periksa setiap penolakan dan buat kebijakan SELinux untuk menanganinya dengan benar. Lihat contoh di Penyesuaian.
Anda harus memulai dengan kebijakan di AOSP, lalu membangunnya untuk penyesuaian Anda sendiri. Untuk mengetahui informasi selengkapnya tentang strategi kebijakan dan melihat lebih dekat beberapa langkah ini, lihat Menulis Kebijakan SELinux.
Kasus penggunaan
Berikut adalah contoh spesifik eksploitasi yang perlu dipertimbangkan saat membuat software Anda sendiri dan kebijakan SELinux terkait:
Symlink: Karena symlink muncul sebagai file, symlink sering kali dibaca sebagai file, yang dapat menyebabkan eksploitasi. Misalnya, beberapa komponen istimewa, seperti init, mengubah izin file tertentu, terkadang menjadi terlalu terbuka.
Penyerang kemudian dapat mengganti file tersebut dengan symlink ke kode yang mereka kontrol, sehingga penyerang dapat mengganti file arbitrer. Namun, jika Anda tahu bahwa aplikasi Anda tidak pernah melintasi symlink, Anda dapat melarangnya melakukannya dengan SELinux.
File sistem: Pertimbangkan class file sistem yang hanya boleh dimodifikasi oleh server sistem. Namun, karena netd, init, dan vold berjalan sebagai root, mereka dapat mengakses file sistem tersebut. Jadi, jika netd disusupi, file tersebut dapat disusupi dan berpotensi menyusupi server sistem itu sendiri.
Dengan SELinux, Anda dapat mengidentifikasi file tersebut sebagai file data server sistem.
Oleh karena itu, satu-satunya domain yang memiliki akses baca/tulis ke domain tersebut adalah server sistem.
Meskipun netd disusupi, netd tidak dapat mengalihkan domain ke domain server sistem dan mengakses file sistem tersebut meskipun berjalan sebagai root.
Data aplikasi: Contoh lainnya adalah class fungsi yang harus dijalankan sebagai root, tetapi tidak boleh mendapatkan akses ke data aplikasi. Hal ini sangat berguna karena berbagai pernyataan dapat dibuat, seperti melarang domain tertentu yang tidak terkait dengan data aplikasi mengakses internet.
setattr: Untuk perintah seperti chmod dan
chown, Anda dapat mengidentifikasi kumpulan file tempat domain terkait dapat melakukan setattr. Apa pun di luar itu dapat dilarang oleh perubahan ini, bahkan oleh root. Jadi, aplikasi dapat menjalankan
chmod dan chown terhadap aplikasi yang diberi label
app_data_files, tetapi tidak shell_data_files
atau system_data_files.