Mengimplementasikan SELinux

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 terkait aturan, jenis, class, izin, dan lainnya. Pertimbangan penuh SELinux berada di luar cakupan dokumen ini, tetapi pemahaman tentang cara menulis aturan kebijakan kini penting saat menyiapkan perangkat Android baru. Sudah ada banyak informasi yang tersedia terkait SELinux. Lihat Dokumentasi dukungan untuk mengetahui resource yang disarankan.

File kunci

Untuk mengaktifkan SELinux, integrasikan kernel Android terbaru, lalu gabungkan file yang ditemukan di direktori system/sepolicy. Saat dikompilasi, file tersebut terdiri dari 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 /device/manufacturer/device-name/sepolicy direktori. Di Android 8.0 dan yang lebih baru, 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 baru, lihat Menyesuaikan SEPolicy di Android 8.0+. Terlepas dari versi Android, Anda masih mengubah 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 Anda.

  • file_contexts menetapkan 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 menerapkan file_contexts, buat ulang image sistem file atau jalankan restorecon pada file yang akan diberi label baru. Pada upgrade, perubahan pada file_contexts akan otomatis diterapkan ke partisi sistem dan data pengguna sebagai bagian dari upgrade. Perubahan juga dapat diterapkan secara otomatis pada upgrade ke partisi lain dengan menambahkan panggilan restorecon_recursive ke file init.board.rc setelah partisi dipasang baca-tulis.
  • genfs_contexts menetapkan label ke sistem file, seperti proc atau vfat yang tidak mendukung atribut yang diperluas. Konfigurasi ini dimuat sebagai bagian dari kebijakan kernel, tetapi perubahan mungkin tidak berlaku untuk inode dalam inti, sehingga memerlukan reboot atau unmounting dan pemasangan ulang sistem file untuk menerapkan perubahan sepenuhnya. Label tertentu juga dapat ditetapkan ke pemasangan tertentu, seperti vfat menggunakan opsi context=mount.
  • property_contexts menetapkan label ke properti sistem Android untuk mengontrol proses yang dapat menetapkannya. Konfigurasi ini dibaca oleh proses init selama startup.
  • service_contexts menetapkan label ke layanan binder Android untuk mengontrol proses yang dapat menambahkan (mendaftarkan) dan menemukan (mencari) referensi binder untuk layanan tersebut. Konfigurasi ini dibaca oleh proses servicemanager selama startup.
  • seapp_contexts menetapkan label ke proses aplikasi dan /data/data direktori. Konfigurasi ini dibaca oleh zygote proses pada setiap peluncuran aplikasi dan oleh installd selama startup.
  • mac_permissions.xml menetapkan tag seinfo ke aplikasi berdasarkan tanda tangan dan secara opsional nama paketnya. Tag seinfo kemudian dapat digunakan sebagai kunci dalam file seapp_contexts untuk menetapkan label tertentu ke semua aplikasi dengan tag seinfo tersebut. Konfigurasi ini dibaca oleh system_server selama startup.
  • keystore2_key_contexts menetapkan label ke namespace Keystore 2. Namespace ini diterapkan oleh daemon keystore2. 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 /device/manufacturer/device-name/BoardConfig.mk makefile Anda untuk mereferensikan subdirektori sepolicy dan setiap file kebijakan baru. Untuk mengetahui informasi selengkapnya tentang variabel BOARD_SEPOLICY, lihat system/sepolicy/README file.

BOARD_SEPOLICY_DIRS += \
        <root>/device/manufacturer/device-name/sepolicy

BOARD_SEPOLICY_UNION += \
        genfs_contexts \
        file_contexts \
        sepolicy.te

Setelah dibuat 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.

Saat file kebijakan baru dan update BoardConfig.mk sudah ada, setelan kebijakan baru akan otomatis dibuat ke dalam file kebijakan kernel akhir. Untuk mengetahui informasi selengkapnya tentang cara sepolicy dibuat di perangkat, lihat Membuat sepolicy.

Penerapan

Untuk memulai SELinux:

  1. Aktifkan SELinux di kernel: CONFIG_SECURITY_SELINUX=y
  2. Ubah parameter kernel_cmdline atau bootconfig sehingga:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    atau
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    Hal ini hanya untuk pengembangan awal kebijakan untuk perangkat. Setelah Anda memiliki kebijakan bootstrap awal, hapus parameter ini agar perangkat Anda menerapkan atau gagal CTS.
  3. Booting sistem dalam mode permisif dan lihat penolakan yang terjadi saat booting:
    Di Ubuntu 14.04 atau yang lebih baru:
    adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
    
    Di Ubuntu 12.04:
    adb pull /sys/fs/selinux/policy
    adb logcat -b all | audit2allow -p policy
    
  4. Evaluasi output untuk mengetahui peringatan yang menyerupai init: Warning! Service name needs a SELinux domain defined; please fix! Lihat Validasi untuk mengetahui petunjuk dan alat.
  5. Identifikasi perangkat, dan file baru lainnya yang memerlukan pemberian label.
  6. Gunakan label yang ada atau baru untuk objek Anda. Lihat file *_contexts untuk melihat cara pemberian label sebelumnya dan gunakan pengetahuan tentang arti label untuk menetapkan label baru. Idealnya, ini adalah label yang ada yang sesuai dengan kebijakan, tetapi terkadang label baru diperlukan, dan aturan untuk akses ke label tersebut diperlukan. Tambahkan label Anda ke file konteks yang sesuai.
  7. Identifikasi domain/proses yang harus memiliki domain keamanan sendiri. Anda mungkin perlu menulis kebijakan yang benar-benar baru untuk setiap domain/proses. Semua layanan yang dibuat dari init, misalnya, harus memiliki layanan sendiri. Perintah berikut membantu mengungkapkan layanan yang tetap berjalan (tetapi SEMUA layanan memerlukan perlakuan seperti itu):
    adb shell su -c ps -Z | grep init
    
    adb shell su -c dmesg | grep 'avc: '
    
  8. Tinjau init.device.rc untuk mengidentifikasi domain yang tidak memiliki jenis domain. Berikan jenis domain lebih awal dalam proses pengembangan Anda untuk menghindari penambahan aturan ke init atau membingungkan akses init dengan akses yang ada dalam kebijakan mereka sendiri.
  9. Siapkan BOARD_CONFIG.mk untuk menggunakan BOARD_SEPOLICY_* variabel. Lihat README di system/sepolicy untuk mengetahui detail tentang cara menyiapkan hal ini.
  10. Periksa file init.device.rc dan fstab.device serta pastikan setiap penggunaan mount sesuai dengan sistem file yang diberi label dengan benar atau opsi context= mount ditentukan.
  11. Tinjau setiap penolakan dan buat kebijakan SELinux untuk menangani setiap penolakan 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 a 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 dibaca sebagai file, yang dapat menyebabkan eksploitasi. Misalnya, beberapa komponen yang memiliki hak 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 menimpa 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 diubah 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 file tersebut adalah server sistem. Meskipun netd disusupi, domain tersebut tidak dapat beralih ke domain server sistem dan mengakses file sistem tersebut meskipun berjalan sebagai root.

Data aplikasi: Contoh lainnya adalah class fungsi yang harus berjalan sebagai root, tetapi tidak boleh mengakses data aplikasi. Hal ini sangat berguna karena pernyataan yang luas dapat dibuat, seperti domain tertentu yang tidak terkait dengan data aplikasi dilarang mengakses internet.

setattr: Untuk perintah seperti chmod dan chown, Anda dapat mengidentifikasi kumpulan file tempat domain terkait dapat melakukan setattr. Apa pun di luar hal tersebut dapat dilarang dari perubahan ini, bahkan oleh root. Jadi, aplikasi dapat menjalankan chmod dan chown terhadap file yang diberi label app_data_files, tetapi bukan shell_data_files atau system_data_files.