Menulis Kebijakan SELinux

Proyek Open Source Android (AOSP) menyediakan kebijakan dasar yang solid untuk aplikasi dan layanan yang umum di semua perangkat Android. Kontributor AOSP secara rutin menyempurnakan kebijakan ini. Kebijakan inti diharapkan hingga 90–95% dari kebijakan pada perangkat final dengan penyesuaian yang membentuk 5–10% sisanya. Artikel ini berfokus pada penyesuaian khusus perangkat, cara menulis kebijakan khusus perangkat, dan beberapa perangkap yang harus dihindari di sepanjang jalan.

Tampilan perangkat

Saat menulis kebijakan khusus perangkat, ikuti langkah-langkah berikut.

Menjalankan dalam mode permisif

Saat perangkat berada di mode permisif, penolakan dicatat tetapi tidak diberlakukan. Mode permisif penting bagi dua orang alasan:

  • Mode permisif memastikan bahwa pembahasan kebijakan tidak menunda penghentian awal tugas memunculkan perangkat.
  • Penolakan yang diberlakukan dapat menyamarkan penolakan lainnya. Misalnya, akses file biasanya memerlukan pencarian direktori, pembukaan file, lalu pembacaan file. Di beberapa menerapkan mode pemberlakuan, hanya penolakan pencarian direktori yang akan terjadi. Permisif memastikan semua penolakan terlihat.

Cara paling sederhana untuk mengatur perangkat ke mode permisif adalah menggunakan perintah kernel baris. File ini dapat ditambahkan ke file BoardConfig.mk perangkat: platform/device/<vendor>/<target>/BoardConfig.mk. Setelah mengubah command line, lakukan make clean, lalu make bootimage, lalu flash image booting baru.

Setelah itu, konfirmasi mode permisif dengan:

adb shell getenforce

Dua minggu adalah waktu yang wajar untuk berada dalam mode permisif global. Setelah mengatasi sebagian besar penolakan, kembalilah ke mode penegakan dan untuk menangani {i>bug<i} saat masuk. Domain masih menghasilkan penolakan atau layanan yang sedang dalam pengembangan dapat diubah ke mode permisif, namun mereka kembali ke mode penerapan sesegera mungkin.

Terapkan lebih awal

Dalam mode pemberlakuan, penolakan dicatat dan diterapkan. Ini adalah yang terbaik agar perangkat Anda dapat menerapkan mode sedini mungkin. Menunggu untuk membuat dan menerapkan kebijakan khusus perangkat sering kali menghasilkan produk yang berisi bug dan pengalaman pengguna yang buruk. Mulai cukup awal untuk berpartisipasi dalam dogfood dan memastikan cakupan pengujian fungsi sepenuhnya dalam penggunaan di dunia nyata. Memulai sejak dini memastikan masalah keamanan menjadi informasi dalam keputusan desain. Sebaliknya, memberikan izin yang hanya berdasarkan pada penolakan yang diamati adalah pendekatan yang tidak aman. Gunakan ini waktu untuk melakukan audit keamanan perangkat dan melaporkan {i>bug<i} terhadap perilaku yang seharusnya tidak diizinkan.

Menghapus atau menghapus kebijakan yang ada

Ada sejumlah alasan bagus untuk membuat kebijakan khusus perangkat dari goresan di perangkat baru, yang meliputi:

Mengatasi penolakan layanan inti

Penolakan yang dihasilkan oleh layanan inti biasanya ditangani dengan pelabelan file. Contoh:

avc: denied { open } for pid=1003 comm=”mediaserver” path="/dev/kgsl-3d0”
dev="tmpfs" scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0
tclass=chr_file permissive=1
avc: denied { read write } for pid=1003 name="kgsl-3d0" dev="tmpfs"
scontext=u:r:mediaserver:s0
tcontext=u:object_r:device:s0 tclass=chr_file permissive=1

sudah ditangani sepenuhnya dengan memberi label /dev/kgsl-3d0 yang benar. Di beberapa contoh ini, tcontext adalah device. Hal ini mewakili konteks default saat semua yang ada di /dev menerima ” device” kecuali label yang lebih spesifik ditetapkan. Menerima saja {i>output <i}dari audit2izin di sini akan menghasilkan aturan yang salah dan terlalu permisif.

Untuk mengatasi masalah seperti ini, berikan label yang lebih spesifik, yang di kasus ini adalah gpu_device. Tidak ada izin lebih lanjut yang diperlukan karena server media telah memiliki izin yang diperlukan dalam kebijakan inti untuk mengakses gpu_device.

File khusus perangkat lainnya yang harus diberi label dengan jenis yang telah ditentukan di kebijakan inti:

Secara umum, memberikan izin ke label {i>default<i} keliru. Banyak di antaranya izin tidak diizinkan oleh neverallow, tapi bahkan ketika tidak secara eksplisit dilarang, praktik terbaik adalah memberikan label.

Beri label layanan dan alamat baru penolakan

Layanan yang diluncurkan init harus berjalan di domain SELinux-nya sendiri. Tujuan Contoh berikut menempatkan layanan “foo” ke dalam domain SELinux-nya sendiri dan memberikannya izin akses.

Layanan ini diluncurkan di File init.device.rc sebagai:

service foo /system/bin/foo
    class core
  1. Buat domain baru "foo"

    Membuat file device/manufacturer/device-name/sepolicy/foo.te dengan konten berikut:

    # foo service
    type foo, domain;
    type foo_exec, exec_type, file_type;
    
    init_daemon_domain(foo)
    

    Ini adalah {i>template<i} awal untuk domain {i>foo<i} SELinux, yang dapat menambahkan aturan berdasarkan operasi tertentu yang dilakukan oleh {i>executable<i} itu.

  2. Beri label /system/bin/foo

    Tambahkan kode berikut ke device/manufacturer/device-name/sepolicy/file_contexts:

    /system/bin/foo   u:object_r:foo_exec:s0
    

    Ini memastikan {i>executable<i} diberi label dengan benar sehingga SELinux menjalankan domain publik di domain yang tepat.

  3. Membangun dan mem-flash boot serta image sistem.
  4. Sempurnakan aturan SELinux untuk domain.

    Gunakan penolakan untuk menentukan izin yang diperlukan. Tujuan audit2izin memberikan pedoman yang baik, tetapi hanya menggunakannya untuk menginformasikan menulis. Jangan hanya menyalin outputnya.

Beralih kembali ke mode penerapan

Tidak masalah untuk memecahkan masalah dalam mode permisif, tetapi beralihlah kembali ke penerapan sedini mungkin dan cobalah untuk tetap berada di sana.

Kesalahan umum

Berikut adalah beberapa solusi untuk kesalahan umum yang terjadi saat menulis kebijakan khusus perangkat.

Penggunaan negasi yang berlebihan

Contoh aturan berikut adalah seperti mengunci pintu depan tetapi meninggalkan jendela terbuka:

allow { domain -untrusted_app } scary_debug_device:chr_file rw_file_perms

Intentnya jelas: semua orang, kecuali aplikasi pihak ketiga, dapat memiliki akses ke debug perangkat seluler.

Aturan ini memiliki beberapa kesalahan. Pengecualian untrusted_app mudah untuk diatasi karena semua aplikasi dapat secara opsional menjalankan layanan di domain isolated_app. Demikian pula, jika domain baru untuk aplikasi pihak ketiga ditambahkan ke AOSP, mereka juga akan memiliki akses ke scary_debug_device. Aturan ini terlalu permisif. Sebagian besar domain tidak akan mendapat manfaat dari akses ke alat debug ini. Aturan harus ditulis agar hanya mengizinkan domain yang memerlukan akses.

Proses debug fitur dalam produksi

Fitur debug tidak boleh ada di build produksi dan tidak boleh ada lebih lanjut.

Alternatif yang paling sederhana adalah dengan hanya mengizinkan fitur {i>debug<i} saat SELinux dinonaktifkan pada build eng/userdebug, seperti adb root dan adb shell setenforce 0.

Alternatif aman lainnya adalah dengan menyertakan izin akses debug dalam pernyataan userdebug_or_eng.

Ledakan ukuran kebijakan

Menentukan Karakteristik Kebijakan SEAndroid di Alam Liar menjelaskan tren yang mengkhawatirkan tentang pertumbuhan penyesuaian kebijakan perangkat. Kebijakan khusus perangkat harus mencakup 5–10% dari keseluruhan kebijakan yang berjalan di perangkat. Penyesuaian dalam kisaran 20%+ hampir pasti mengandung lebih dari domain istimewa, dan kebijakan yang sudah tidak berlaku.

Kebijakan yang terlalu besar:

  • Mengambil memori ganda karena kebijakan ini ada di dalam ramdisk dan juga dimuat ke dalam memori kernel.
  • Mengurangi kapasitas disk dengan mengharuskan bootimage yang lebih besar.
  • Memengaruhi waktu pencarian kebijakan runtime.

Contoh berikut menunjukkan dua perangkat dengan 50% dan 40% dari kebijakan di perangkat. Penulisan ulang kebijakan menghasilkan peningkatan keamanan substansial tanpa menghilangkan fungsionalitas, seperti seperti yang ditampilkan di bawah ini. (Perangkat AOSP, Shamu dan Flounder disertakan untuk perbandingan.)

Gambar 1: Perbandingan ukuran kebijakan spesifik per perangkat setelah audit keamanan.

Gambar 1. Perbandingan perangkat tertentu ukuran kebijakan setelah audit keamanan.

Dalam kedua kasus tersebut, kebijakan tersebut telah berkurang secara drastis baik dalam hal ukuran maupun jumlahnya izin akses. Penurunan ukuran kebijakan hampir sepenuhnya disebabkan oleh penghapusan izin yang tidak perlu, yang banyak di antaranya mungkin merupakan aturan yang dibuat oleh audit2allow yang ditambahkan secara acak ke kebijakan. Mati domain juga menjadi masalah di kedua perangkat.

Memberikan kemampuan dac_override

Penolakan dac_override berarti bahwa proses yang melanggar kebijakan mencoba mengakses file dengan izin akses pengguna/grup/dunia unix yang salah. Solusi yang tepat hampir tidak pernah memberikan izin dac_override. Sebagai gantinya mengubah izin unix pada file atau proses. Beberapa domain seperti init, vold, dan installd benar-benar memerlukan kemampuan untuk mengganti izin akses file unix untuk mengakses file proses lain. Lihat blog Dan Walsh untuk penjelasan yang lebih mendalam.