Menerapkan SELinux

SELinux diatur ke default-deny, yang berarti bahwa setiap akses tunggal yang memiliki kait di kernel harus secara eksplisit diizinkan oleh kebijakan. Ini berarti file kebijakan terdiri dari sejumlah besar informasi mengenai aturan, jenis, kelas, izin, dan banyak lagi. Pertimbangan lengkap SELinux berada di luar cakupan dokumen ini, tetapi pemahaman tentang cara menulis aturan kebijakan kini penting saat memunculkan perangkat Android baru. Ada banyak informasi yang tersedia mengenai SELinux. Lihat Dokumentasi pendukung untuk sumber daya yang disarankan.

File kunci

Untuk mengaktifkan SELinux, integrasikan kernel Android terbaru dan kemudian gabungkan file yang ditemukan di direktori system/sepolicy . Saat dikompilasi, file-file tersebut terdiri dari kebijakan keamanan kernel SELinux dan mencakup sistem operasi Android upstream.

Secara umum, Anda tidak boleh memodifikasi 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 seharusnya hanya memengaruhi kebijakan di direktori vendor Anda. Untuk detail selengkapnya tentang pemisahan kebijakan publik di Android 8.0 dan lebih tinggi, lihat Menyesuaikan SEPolicy di Android 8.0+ . Terlepas dari versi Android, Anda masih memodifikasi file-file ini:

File kebijakan

File yang diakhiri dengan *.te adalah file sumber kebijakan SELinux, yang mendefinisikan 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 memberikan label ke file dan digunakan oleh berbagai komponen userspace. Saat Anda membuat kebijakan baru, buat atau perbarui file ini untuk menetapkan label baru ke file. Untuk menerapkan file_contexts baru, bangun kembali gambar sistem file atau jalankan restorecon pada file yang akan diberi label ulang. Pada pemutakhiran, perubahan pada file_contexts secara otomatis diterapkan ke sistem dan partisi data pengguna sebagai bagian dari pemutakhiran. Perubahan juga dapat diterapkan secara otomatis pada peningkatan ke partisi lain dengan menambahkan panggilan restorecon_recursive ke init Anda. board .rc file setelah partisi telah dipasang baca-tulis.
  • genfs_contexts memberikan 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 inti, memerlukan reboot atau melepas dan memasang kembali sistem file untuk menerapkan perubahan sepenuhnya. Label tertentu juga dapat ditetapkan ke mount tertentu, seperti vfat menggunakan opsi context=mount .
  • property_contexts memberikan label ke properti sistem Android untuk mengontrol proses apa yang dapat menyetelnya. Konfigurasi ini dibaca oleh proses init selama startup.
  • service_contexts memberikan label ke layanan pengikat Android untuk mengontrol proses apa yang dapat menambahkan (mendaftar) dan menemukan (mencari) referensi pengikat untuk layanan tersebut. Konfigurasi ini dibaca oleh proses servicemanager selama startup.
  • seapp_contexts memberikan label ke proses aplikasi dan direktori /data/data . Konfigurasi ini dibaca oleh proses zygote pada setiap peluncuran aplikasi dan oleh installd selama startup.
  • mac_permissions.xml memberikan tag seinfo ke aplikasi berdasarkan tanda tangannya 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 . Konfigurasi ini dibaca oleh system_server saat startup.
  • keystore2_key_contexts memberikan label ke ruang nama Keystore 2.0. Namespace ini diberlakukan oleh daemon keystore2. Keystore selalu menyediakan ruang nama berbasis UID/AID. Keystore 2.0 juga memberlakukan ruang nama yang ditentukan oleh kebijakan. Penjelasan rinci tentang format dan konvensi file ini dapat ditemukan di sini .

BoardConfig.mk makefile

Setelah mengedit atau menambahkan file kebijakan dan konteks, perbarui makefile /device/ manufacturer / device-name /BoardConfig.mk untuk merujuk ke subdirektori sepolicy dan setiap file kebijakan baru. Untuk informasi lebih lanjut 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 membangun kembali, perangkat Anda diaktifkan dengan SELinux. Anda sekarang dapat menyesuaikan kebijakan SELinux Anda untuk mengakomodasi penambahan Anda sendiri ke sistem operasi Android seperti yang dijelaskan dalam Kustomisasi atau memverifikasi pengaturan yang ada seperti yang tercakup dalam Validasi .

Ketika file kebijakan baru dan pembaruan BoardConfig.mk tersedia, pengaturan kebijakan baru secara otomatis dibangun ke dalam file kebijakan kernel akhir. Untuk informasi selengkapnya tentang bagaimana kebijakan dibuat di perangkat, lihat Membangun kebijakan .

Penerapan

Untuk memulai dengan 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
    Ini hanya untuk pengembangan awal kebijakan perangkat. Setelah Anda memiliki kebijakan bootstrap awal, hapus parameter ini sehingga perangkat Anda menerapkan atau akan gagal CTS.
  3. Boot sistem secara permisif dan lihat penolakan apa yang ditemui saat boot:
    Di Ubuntu 14.04 atau 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 peringatan yang menyerupai init: Warning! Service name needs a SELinux domain defined; please fix! Lihat Validasi untuk petunjuk dan alat.
  5. Identifikasi perangkat, dan file baru lainnya yang perlu diberi label.
  6. Gunakan label yang ada atau baru untuk objek Anda. Lihat file *_contexts untuk melihat bagaimana sesuatu diberi label sebelumnya dan gunakan pengetahuan tentang arti label untuk menetapkan yang baru. Idealnya, ini akan menjadi label yang sudah ada yang sesuai dengan kebijakan, tetapi terkadang label baru akan dibutuhkan, dan aturan untuk akses ke label itu akan diperlukan. Tambahkan label Anda ke file konteks yang sesuai.
  7. Identifikasi domain/proses yang harus memiliki domain keamanannya sendiri. Anda mungkin perlu menulis kebijakan yang sama sekali baru untuk masing-masing. Semua layanan yang muncul dari init , misalnya, harus memiliki sendiri. Perintah berikut membantu mengungkapkan yang tetap berjalan (tetapi SEMUA layanan memerlukan perawatan 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 apa pun yang tidak memiliki tipe domain. Beri mereka domain di awal proses pengembangan Anda untuk menghindari penambahan aturan ke init atau membingungkan akses init dengan yang ada dalam kebijakan mereka sendiri.
  9. Siapkan BOARD_CONFIG.mk untuk menggunakan variabel BOARD_SEPOLICY_* . Lihat README di system/sepolicy untuk detail tentang pengaturan ini.
  10. Periksa init. device .rc dan fstab. device dan pastikan setiap penggunaan mount sesuai dengan sistem file yang diberi label dengan benar atau bahwa opsi context= mount ditentukan.
  11. Telusuri setiap penolakan dan buat kebijakan SELinux untuk menangani setiap penolakan dengan benar. Lihat contoh di Kustomisasi .

Anda harus mulai dengan kebijakan di AOSP dan kemudian membangunnya untuk penyesuaian Anda sendiri. Untuk informasi lebih lanjut tentang strategi kebijakan dan melihat lebih dekat beberapa langkah ini, lihat Menulis Kebijakan SELinux .

Gunakan kasus

Berikut adalah contoh spesifik eksploitasi yang perlu dipertimbangkan saat membuat perangkat lunak Anda sendiri dan kebijakan SELinux terkait:

Symlinks - Karena symlink muncul sebagai file, mereka sering 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, memungkinkan penyerang untuk menimpa file arbitrer. Tetapi jika Anda tahu aplikasi Anda tidak akan pernah melintasi symlink, Anda dapat melarangnya melakukannya dengan SELinux.

File sistem - Pertimbangkan kelas file sistem yang harus dimodifikasi hanya oleh server sistem. Namun, karena netd , init , dan vold dijalankan sebagai root, mereka dapat mengakses file sistem tersebut. Jadi jika netd dikompromikan, itu bisa membahayakan file-file itu dan berpotensi server sistem itu sendiri.

Dengan SELinux, Anda dapat mengidentifikasi file-file tersebut sebagai file data server sistem. Oleh karena itu, satu-satunya domain yang memiliki akses baca/tulis ke mereka adalah server sistem. Bahkan jika netd dikompromikan, itu tidak dapat mengalihkan domain ke domain server sistem dan mengakses file sistem tersebut meskipun berjalan sebagai root.

Data aplikasi - Contoh lain adalah kelas fungsi yang harus dijalankan sebagai root tetapi tidak boleh mengakses data aplikasi. Ini sangat berguna karena pernyataan luas dapat dibuat, seperti domain tertentu yang tidak terkait dengan data aplikasi yang dilarang mengakses internet.

setattr - Untuk perintah seperti chmod dan chown , Anda dapat mengidentifikasi kumpulan file di mana domain terkait dapat melakukan setattr . Apa pun di luar itu dapat dilarang dari perubahan ini, bahkan oleh root. Jadi aplikasi mungkin menjalankan chmod dan chown terhadap app_data_files berlabel tersebut tetapi tidak shell_data_files atau system_data_files .