Android sangat menganjurkan OEM untuk menguji implementasi SELinux mereka secara menyeluruh. Saat produsen menerapkan SELinux, mereka harus menerapkan kebijakan baru ke kumpulan perangkat uji terlebih dahulu.
Setelah menerapkan kebijakan baru, pastikan SELinux berjalan dalam mode yang benar di perangkat dengan mengeluarkan perintah getenforce
.
Ini mencetak mode SELinux global: Enforcing atau Permissive. Untuk menentukan mode SELinux untuk setiap domain, Anda harus memeriksa file yang sesuai atau menjalankan versi terbaru sepolicy-analyze
dengan flag ( -p
) yang sesuai, yang 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 ke dmesg
pada perangkat ini dan menyempurnakan pengaturan sebelum rilis publik dalam mode permisif dan akhirnya beralih ke mode penegakan. Pesan log SELinux berisi avc:
dan 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
.
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 mengubah 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
Interpretasikan output ini seperti ini:
-
{ connectto }
di atas mewakili tindakan yang diambil. Bersama dengantclass
di akhir (unix_stream_socket
), ini memberi tahu Anda secara kasar apa yang sedang dilakukan untuk 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 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 -
scontext
(konteks sumber) mewakili aktor, dalam hal ini daemonrmt_storage
. - Objek -
tcontext
(konteks target) mewakili objek yang sedang ditindaklanjuti, dalam hal ini kmem. - Hasil -
tclass
(kelas target) menunjukkan jenis objek yang ditindaklanjuti, dalam hal inichr_file
(perangkat karakter).
Membuang Tumpukan Pengguna dan Kernel
Dalam beberapa kasus, informasi yang terkandung dalam log peristiwa tidak cukup untuk menunjukkan dengan tepat asal penolakan. Seringkali berguna untuk mengumpulkan rantai panggilan, termasuk kernel dan ruang pengguna, untuk lebih memahami mengapa penolakan terjadi.
Kernel terbaru mendefinisikan sebuah 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 . - Seharusnya dimungkinkan untuk mereproduksi acara yang Anda debug. Peristiwa waktu booting tidak didukung menggunakan simpleperf; namun Anda mungkin masih dapat memulai ulang layanan untuk memicu acara.
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 harus dipicu. Setelah itu, perekaman harus dihentikan. Dalam contoh ini, dengan menggunakan Ctrl-c
, sampel seharusnya sudah diambil:
^Csimpleperf I cmd_record.cpp:751] Samples recorded: 1. Samples lost: 0.
Akhirnya, simpleperf report
dapat digunakan untuk memeriksa stacktrace yang ditangkap. Misalnya:
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 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 lebih lanjut tentang simpleperf
, lihat referensi perintah Simpleperf Executable
Beralih ke permisif
Penegakan SELinux dapat dinonaktifkan melalui ADB pada userdebug atau eng build. Untuk melakukannya, pertama-tama alihkan ADB ke root dengan menjalankan adb root
. Kemudian, untuk menonaktifkan penegakan 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 sangat 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 kemungkinan tambahan untuk izin yang melampaui batas. Misalnya, memberi makan audit2allow
penolakan rmt_storage
yang ditampilkan 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 memberikan rmt
kemampuan untuk menulis memori kernel, lubang keamanan yang mencolok. Seringkali pernyataan audit2allow
hanyalah titik awal. Setelah menggunakan pernyataan ini, Anda mungkin perlu mengubah domain sumber dan label target, serta memasukkan makro yang tepat, untuk sampai pada kebijakan yang baik. Terkadang penolakan yang diperiksa seharusnya tidak menghasilkan perubahan kebijakan sama sekali; alih-alih aplikasi yang menyinggung harus diubah.