Android sangat menganjurkan OEM untuk menguji implementasi SELinux mereka secara menyeluruh. Saat produsen menerapkan SELinux, mereka harus menerapkan kebijakan baru pada kumpulan pengujian perangkat terlebih dahulu.
Setelah menerapkan kebijakan baru, pastikan SELinux berjalan dalam mode yang benar di perangkat dengan mengeluarkan perintah getenforce
.
Ini mencetak mode SELinux global: Menegakkan atau Permisif. Untuk menentukan mode SELinux untuk setiap domain, Anda harus memeriksa file terkait atau menjalankan versi terbaru sepolicy-analyze
dengan tanda ( -p
) yang sesuai, ada di /platform/system/sepolicy/tools/
.
Membaca penolakan
Periksa kesalahan, yang dirutekan sebagai log peristiwa ke dmesg
dan logcat
dan dapat dilihat secara lokal di perangkat. Produsen harus memeriksa keluaran SELinux yang akan dmesg
pada perangkat ini dan menyempurnakan pengaturan sebelum dirilis ke publik dalam mode permisif dan pada akhirnya beralih ke mode penegakan. Pesan log SELinux berisi avc:
sehingga dapat dengan mudah ditemukan dengan grep
. Dimungkinkan untuk menangkap log penolakan yang sedang berlangsung dengan menjalankan cat /proc/kmsg
atau untuk menangkap log penolakan dari boot sebelumnya dengan menjalankan cat /sys/fs/pstore/console-ramoops
.
Pesan kesalahan SELinux dibatasi tingkatnya setelah booting selesai untuk menghindari membanjiri log. Untuk memastikan Anda melihat semua pesan yang relevan, Anda dapat menonaktifkannya dengan menjalankan adb shell auditctl -r 0
.
Dengan keluaran ini, produsen dapat dengan mudah mengidentifikasi ketika pengguna sistem atau komponen melanggar kebijakan SELinux. Produsen kemudian dapat memperbaiki perilaku buruk ini, baik dengan perubahan pada perangkat lunak, kebijakan SELinux, atau keduanya.
Secara khusus, pesan log ini menunjukkan proses apa yang akan gagal dalam mode penegakan dan alasannya. Berikut ini contohnya:
avc: denied { connectto } for pid=2671 comm="ping" path="/dev/socket/dnsproxyd" scontext=u:r:shell:s0 tcontext=u:r:netd:s0 tclass=unix_stream_socket
Tafsirkan keluaran ini seperti ini:
- Tanda
{ connectto }
di atas mewakili tindakan yang diambil. Bersama dengantclass
di akhir (unix_stream_socket
), ini memberi tahu Anda secara kasar apa yang sedang dilakukan terhadap apa. Dalam hal ini, ada sesuatu yang mencoba menyambung ke soket aliran unix. -
scontext (u:r:shell:s0)
memberi tahu Anda konteks apa yang memulai tindakan. Dalam hal ini ini adalah sesuatu yang berjalan sebagai shell. -
tcontext (u:r:netd:s0)
memberi tahu Anda konteks target tindakan. Dalam hal ini, itu adalah unix_stream_socket yang dimiliki olehnetd
. -
comm="ping"
di bagian atas memberi Anda petunjuk tambahan tentang apa yang sedang dijalankan pada saat penolakan dibuat. Dalam hal ini, ini adalah petunjuk yang cukup bagus.
Contoh lain:
adb shell su root dmesg | grep 'avc: '
Keluaran:
<5> type=1400 audit: avc: denied { read write } for pid=177 comm="rmt_storage" name="mem" dev="tmpfs" ino=6004 scontext=u:r:rmt:s0 tcontext=u:object_r:kmem_device:s0 tclass=chr_file
Berikut adalah elemen kunci dari penolakan ini:
- Tindakan - tindakan yang dicoba disorot dalam tanda kurung,
read write
atausetenforce
. - Aktor - Entri
scontext
(konteks sumber) mewakili aktor, dalam hal ini daemonrmt_storage
. - Objek - Entri
tcontext
(konteks target) mewakili objek yang ditindaklanjuti, dalam hal ini kmem. - Hasil - Entri
tclass
(kelas target) menunjukkan jenis objek yang ditindaklanjuti, dalam hal inichr_file
(perangkat karakter).
Membuang Tumpukan Pengguna dan Kernel
Dalam beberapa kasus, informasi yang terdapat dalam log peristiwa tidak cukup untuk menunjukkan dengan tepat asal usul penolakan. Seringkali berguna untuk mengumpulkan rantai panggilan, termasuk kernel dan ruang pengguna, untuk lebih memahami mengapa penolakan terjadi.
Kernel terbaru mendefinisikan tracepoint bernama avc:selinux_audited
. Gunakan Android simpleperf
untuk mengaktifkan tracepoint ini dan menangkap rantai panggilan.
Konfigurasi yang didukung
- Kernel Linux >= 5.10, khususnya cabang utama Android Common Kernel dan android12-5.10 didukung. Cabang Android12-5.4 juga didukung. Anda dapat menggunakan
simpleperf
untuk menentukan apakah tracepoint ditentukan pada perangkat Anda:adb root && adb shell simpleperf list | grep avc:selinux_audited
. Untuk versi kernel lainnya, Anda dapat memilih commit dd81662 dan 30969bc . - Peristiwa yang sedang Anda debug seharusnya dapat direproduksi. Peristiwa waktu boot tidak didukung menggunakan simpleperf; namun Anda mungkin masih dapat memulai ulang layanan untuk memicu peristiwa tersebut.
Menangkap rantai panggilan
Langkah pertama adalah merekam acara menggunakan simpleperf record
:
adb shell -t "cd /data/local/tmp && su root simpleperf record -a -g -e avc:selinux_audited"
Kemudian, peristiwa yang menyebabkan penolakan tersebut harus dipicu. Setelah itu, perekaman harus dihentikan. Dalam contoh ini, dengan menggunakan Ctrl-c
, sampel seharusnya diambil:
^Csimpleperf I cmd_record.cpp:751] Samples recorded: 1. Samples lost: 0.
Terakhir, simpleperf report
dapat digunakan untuk memeriksa pelacakan tumpukan yang ditangkap. Contohnya:
adb shell -t "cd /data/local/tmp && su root simpleperf report -g --full-callgraph" [...] Children Self Command Pid Tid Shared Object Symbol 100.00% 0.00% dmesg 3318 3318 /apex/com.android.runtime/lib64/bionic/libc.so __libc_init | -- __libc_init | -- main toybox_main toy_exec_which dmesg_main klogctl entry_SYSCALL_64_after_hwframe do_syscall_64 __x64_sys_syslog do_syslog selinux_syslog slow_avc_audit common_lsm_audit avc_audit_post_callback avc_audit_post_callback
Rantai panggilan di atas adalah rantai panggilan kernel dan ruang pengguna yang terpadu. Ini memberi Anda pandangan yang lebih baik tentang aliran kode dengan memulai pelacakan dari ruang pengguna hingga ke kernel tempat penolakan terjadi. Untuk informasi selengkapnya tentang simpleperf
, lihat referensi perintah Simpleperf Executable
Beralih ke permisif
Penegakan SELinux dapat dinonaktifkan melalui ADB pada userdebug atau build eng. Untuk melakukannya, pertama alihkan ADB ke root dengan menjalankan adb root
. Kemudian, untuk menonaktifkan penerapan SELinux, jalankan:
adb shell setenforce 0
Atau di baris perintah kernel (selama pembukaan perangkat awal):
androidboot.selinux=permissive
androidboot.selinux=enforcing
Atau melalui bootconfig di Android 12:
androidboot.selinux=permissive
androidboot.selinux=enforcing
Menggunakan audit2allow
Alat audit2allow
mengambil penolakan dmesg
dan mengubahnya menjadi pernyataan kebijakan SELinux yang sesuai. Dengan demikian, ini dapat mempercepat pengembangan SELinux.
Untuk menggunakannya, jalankan:
adb pull /sys/fs/selinux/policy
adb logcat -b events -d | audit2allow -p policy
Namun demikian, kehati-hatian harus diberikan untuk memeriksa setiap potensi penambahan izin yang melampaui batas. Misalnya, memberi makan audit2allow
penolakan rmt_storage
yang ditunjukkan sebelumnya menghasilkan pernyataan kebijakan SELinux yang disarankan berikut ini:
#============= shell ============== allow shell kernel:security setenforce; #============= rmt ============== allow rmt kmem_device:chr_file { read write };
Ini akan memberi rmt
kemampuan untuk menulis memori kernel, sebuah lubang keamanan yang mencolok. Seringkali pernyataan audit2allow
hanya merupakan titik awal. Setelah menerapkan pernyataan ini, Anda mungkin perlu mengubah domain sumber dan label target, serta memasukkan makro yang tepat, untuk mendapatkan kebijakan yang baik. Terkadang penolakan yang diperiksa seharusnya tidak menghasilkan perubahan kebijakan sama sekali; sebaliknya aplikasi yang melanggar harus diubah.