Android sangat menyarankan OEM untuk menguji penerapan SELinux mereka secara menyeluruh. Saat produsen menerapkan SELinux, mereka harus menerapkan kebijakan baru ke kumpulan pengujian perangkat terlebih dahulu.
Setelah menerapkan kebijakan baru, pastikan SELinux berjalan dalam mode
yang benar di perangkat dengan mengeluarkan perintah getenforce
.
Tindakan ini akan mencetak mode SELinux global: Enforcing atau Permissive. Untuk
menentukan mode SELinux untuk setiap domain, Anda harus memeriksa file
yang sesuai atau menjalankan sepolicy-analyze
versi terbaru dengan
flag (-p
) yang sesuai, yang ada di
/platform/system/sepolicy/tools/
.
Penolakan baca
Periksa error, yang dirutekan sebagai log aktivitas ke dmesg
dan logcat
serta dapat dilihat secara lokal di perangkat. Produsen
harus memeriksa output SELinux ke dmesg
di perangkat ini dan
meningkatkan setelan sebelum rilis publik dalam mode permisif dan akhirnya beralih
ke mode penerapan. Pesan log SELinux berisi avc:
sehingga dapat
ditemukan dengan mudah menggunakan grep
. Anda dapat mengambil log penolakan
yang sedang berlangsung dengan menjalankan cat /proc/kmsg
atau mengambil log penolakan
dari booting sebelumnya dengan menjalankan
cat /sys/fs/pstore/console-ramoops
.
Pesan error SELinux dibatasi kapasitasnya setelah booting selesai untuk menghindari log yang penuh. Untuk memastikan Anda melihat semua pesan yang relevan, Anda dapat menonaktifkannya
dengan menjalankan adb shell auditctl -r 0
.
Dengan output ini, produsen dapat dengan mudah mengidentifikasi kapan pengguna atau komponen sistem melanggar kebijakan SELinux. Produsen kemudian dapat memperbaiki perilaku buruk ini, baik dengan perubahan pada software, kebijakan SELinux, atau keduanya.
Secara khusus, pesan log ini menunjukkan proses apa yang akan gagal dalam mode penerapan 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 berikut:
-
{ connectto }
di atas mewakili tindakan yang dilakukan. Bersama dengantclass
di akhir (unix_stream_socket
), kode ini memberi tahu Anda secara kasar apa yang dilakukan pada apa. Dalam hal ini, ada sesuatu yang mencoba terhubung ke soket streaming unix. -
scontext (u:r:shell:s0)
memberi tahu Anda konteks 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 berjalan pada saat penolakan dibuat. Dalam hal ini, ini adalah petunjuk yang cukup bagus.
Contoh lain:
adb shell su root dmesg | grep 'avc: '
Output:
<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 utama dari penolakan ini:
- Action - tindakan yang dicoba ditandai dalam tanda kurung,
read write
atausetenforce
. - Pelaku - Entri
scontext
(konteks sumber) mewakili pelaku, dalam hal ini daemonrmt_storage
. - Objek - Entri
tcontext
(konteks target) mewakili objek yang ditindaklanjuti, dalam hal ini kmem. - Hasil - Entri
tclass
(class target) menunjukkan jenis objek yang ditindaklanjuti, dalam hal inichr_file
(perangkat karakter).
Men-dump stack pengguna dan kernel
Dalam beberapa kasus, informasi yang terdapat dalam log peristiwa tidak memadai untuk menentukan asal penolakan. Sering kali berguna untuk mengumpulkan rantai panggilan, termasuk kernel dan ruang pengguna, untuk lebih memahami alasan penolakan terjadi.
Kernel terbaru menentukan tracepoint bernama avc:selinux_audited
. Gunakan Android
simpleperf
untuk mengaktifkan tracepoint ini dan mengambil callchain.
Konfigurasi yang didukung
- Kernel Linux >= 5.10, khususnya cabang Kernel Umum Android
mainline
dan
android12-5.10
didukung.
Cabang android12-5.4
juga didukung. Anda dapat menggunakan
simpleperf
untuk menentukan apakah tracepoint ditentukan di perangkat Anda:adb root && adb shell simpleperf list | grep avc:selinux_audited
. Untuk versi kernel lainnya, Anda dapat memilih commit dd81662 dan 30969bc. - Anda seharusnya dapat mereproduksi peristiwa yang sedang di-debug. Peristiwa waktu booting tidak didukung menggunakan simpleperf; namun, Anda mungkin masih dapat memulai ulang layanan untuk memicu peristiwa.
Merekam rantai panggilan
Langkah pertama adalah merekam peristiwa 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 telah diambil:
^Csimpleperf I cmd_record.cpp:751] Samples recorded: 1. Samples lost: 0.
Terakhir, simpleperf report
dapat digunakan untuk memeriksa stacktrace yang diambil.
Sebagai contoh:
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. Hal ini memberi Anda tampilan
alur kode yang lebih baik dengan memulai rekaman aktivitas dari ruang pengguna hingga ke kernel tempat
penolakan terjadi. Untuk informasi selengkapnya tentang simpleperf
, lihat
Referensi perintah yang Dapat dieksekusi Simpleperf
Beralih ke permisif
Penerapan SELinux dapat dinonaktifkan dengan adb pada build userdebug atau eng. Untuk melakukannya,
alihkan ADB ke root terlebih dahulu dengan menjalankan adb root
. Kemudian, untuk menonaktifkan penerapan
SELinux, jalankan:
adb shell setenforce 0
Atau di command line kernel (selama pengaktifan 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
mengonversinya menjadi pernyataan kebijakan SELinux yang sesuai. Dengan demikian, hal ini dapat
sangat mempercepat pengembangan SELinux.
Untuk menggunakannya, jalankan:
adb pull /sys/fs/selinux/policy
adb logcat -b events -d | audit2allow -p policy
Namun, Anda harus berhati-hati untuk memeriksa setiap potensi penambahan izin yang terlalu luas. Misalnya, memberi audit2allow
penolakan
rmt_storage
yang ditampilkan sebelumnya akan menghasilkan pernyataan kebijakan
SELinux yang disarankan berikut:
#============= shell ============== allow shell kernel:security setenforce; #============= rmt ============== allow rmt kmem_device:chr_file { read write };
Hal ini akan memberi rmt
kemampuan untuk menulis memori kernel, lubang keamanan yang mencolok. Sering kali pernyataan audit2allow
hanya merupakan
titik awal. Setelah menerapkan pernyataan ini, Anda mungkin perlu mengubah
domain sumber dan label target, serta menyertakan makro
yang sesuai, untuk mendapatkan kebijakan yang baik. Terkadang penolakan yang sedang diperiksa seharusnya
tidak menghasilkan perubahan kebijakan apa pun; aplikasi yang melanggar
harus diubah.