Android zdecydowanie zachęca producentów OEM do testowania implementacji SELinux. bardzo szybko. W miarę wdrażania SELinux producenci powinni stosować nowe do puli testowej urządzeń.
Po zastosowaniu nowej zasady sprawdź, czy SELinux działa w odpowiednim trybie na urządzeniu. Aby to zrobić, uruchom polecenie getenforce
.
Powoduje to wydrukowanie globalnego trybu SELinux: wymuszania lub mniej rygorystycznego. Aby określić tryb SELinux dla każdej domeny, musisz sprawdzić odpowiednie pliki lub uruchomić najnowszą wersję sepolicy-analyze
z odpowiednią flagą (-p
), która znajduje się w /platform/system/sepolicy/tools/
.
Odczytaj odmowy
Sprawdź, czy nie ma błędów, które są kierowane jako logi zdarzeń na adres dmesg
i logcat
. Są one widoczne lokalnie na urządzeniu. Producenci
powinien sprawdzić wyjście SELinux na dmesg
na tych urządzeniach i
dopracować ustawienia przed opublikowaniem wersji w trybie mniej rygorystycznym
w trybie wymuszania. Wiadomości z dziennika SELinux zawierają avc:
, więc można je łatwo znaleźć za pomocą grep
. Aby przechwycić bieżące logi odmowy, uruchom cat /proc/kmsg
. Aby przechwycić logi odmowy z poprzedniego uruchomienia, uruchom cat /sys/fs/pstore/console-ramoops
.
Częstotliwość komunikatów o błędach SELinux jest ograniczona po zakończeniu uruchamiania, aby zapobiec przewadze prądu.
dzienniki. Aby mieć pewność, że widzisz wszystkie odpowiednie wiadomości, możesz wyłączyć tę funkcję, adb shell auditctl -r 0
.
Na podstawie tych danych producenci mogą łatwo określić, czy użytkownicy systemu Naruszają zasadę SELinux. Producenci mogą naprawić to złe zachowanie, wprowadzając zmiany w oprogramowaniu lub zasadach SELinux albo w obu tych elementach.
W szczególności te komunikaty wskazują, które procesy nie będą działać w trybie egzekwowania i dlaczego. Oto przykład:
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
Zinterpretuj te dane wyjściowe w następujący sposób:
-
{ connectto }
powyżej wskazuje podjęte działanie. Wraz ztclass
na końcu (unix_stream_socket
) informuje, co zostało zrobione i dla kogo. W tym przypadku coś próbowało nawiązać połączenie z gniazdem strumieniowym Unixa. -
scontext (u:r:shell:s0)
informuje, w jakim kontekście zainicjowano działanie. W tym przypadku jest to coś, co działa jako powłoka. -
tcontext (u:r:netd:s0)
informuje o kontekście celu działania. W w tym przypadku jest to sieć unix_stream_socket należąca donetd
. - Element
comm="ping"
na górze zawiera dodatkową wskazówkę dotyczącą uruchamianych w momencie wygenerowania odmowy. W tym przypadku jest to całkiem dobry wskazówek.
Inny przykład:
adb shell su root dmesg | grep 'avc: '
Urządzenie wyjściowe:
<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
Oto najważniejsze elementy tej odmowy:
- Działanie – próba wykonania działania jest podświetlona w nawiasie.
read write
lubsetenforce
. - Uczestnik – wpis
scontext
(kontekst źródła) reprezentuje uczestnika, w tym przypadku demonarmt_storage
. - Obiekt – wpis
tcontext
(kontekst docelowy) reprezentuje na obiekt, na którym wykonano działanie, w tym przypadku kmem. - Wynik – wpis
tclass
(klasa docelowa) wskazuje typ obiektu, na którym wykonywane jest działanie, w tym przypadkuchr_file
(urządzenie znakowe).
Wydumpowanie stosów użytkownika i jądra
W niektórych przypadkach informacje zawarte w dzienniku zdarzeń nie wystarczą do zidentyfikowania źródło zaprzeczania. Aby lepiej zrozumieć, dlaczego doszło do odrzucenia, często warto zebrać łańcuch wywołań, w tym dotyczące jądra i przestrzeni użytkownika.
Najnowsze jądra definiują punkt śledzenia o nazwie avc:selinux_audited
. Użyj Androida
simpleperf
, aby włączyć ten punkt śledzenia i przechwycić łańcuch wywołań.
Obsługiwana konfiguracja
- Jądro systemu Linux >= 5.10, zwłaszcza typowe gałęzie jądra systemu Android
mainline
oraz
android12–5.10
są obsługiwane.
Obsługiwana jest też gałąź android12-5.4. Możesz użyć parametru
simpleperf
, aby określić, czy punkt śledzenia to zdefiniowane na urządzeniu:adb root && adb shell simpleperf list | grep avc:selinux_audited
W przypadku innych wersji jądra możesz wybrać zatwierdzenia. dd81662 oraz 30969bc. - Możliwe jest odtworzenie debugowanego zdarzenia. Zdarzenia w momencie uruchomienia nie są obsługiwane za pomocą Simpleperf; ale wciąż możesz spróbować ponownie ją uruchomić, aby aktywować usługę. do zdarzenia.
Rejestrowanie łańcucha wywołań
Najpierw należy zarejestrować zdarzenie za pomocą funkcji simpleperf record
:
adb shell -t "cd /data/local/tmp && su root simpleperf record -a -g -e avc:selinux_audited"
Następnie powinno zostać wywołane zdarzenie, które spowodowało odrzucenie. Następnie nagrywanie powinno zostać zatrzymane. W tym przykładzie próbka zostałaby zarejestrowana za pomocą funkcji Ctrl-c
:
^Csimpleperf I cmd_record.cpp:751] Samples recorded: 1. Samples lost: 0.
Na koniec możesz użyć parametru simpleperf report
, aby sprawdzić zarejestrowany ślad stosu.
Przykłady:
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
Powyższy łańcuch wywołań to ujednolicony jądro i łańcuch wywołań przestrzeni użytkownika. Zapewnia
przepływu kodu przez uruchomienie śledzenia od przestrzeni użytkownika aż do jądra systemu
następuje zaprzeczanie. Więcej informacji o simpleperf
znajdziesz tutaj:
Dokumentacja poleceń wykonywalnych Simpleperf
Przełącz na mniej rygorystyczny
Egzekwowanie SELinux można wyłączyć za pomocą narzędzia adb w kompilacji userdebug lub eng. Aby to zrobić:
Najpierw przełącz ADB na konto roota, uruchamiając adb root
. Aby wyłączyć SELinux, uruchom:
adb shell setenforce 0
W wierszu poleceń jądra (podczas wcześniejszego wywołania urządzenia):
androidboot.selinux=permissive
androidboot.selinux=enforcing
Możesz też użyć bootconfig w Androidzie 12:
androidboot.selinux=permissive
androidboot.selinux=enforcing
Używaj audyt2allow
Narzędzie audit2allow
przekształca zaprzeczenia dmesg
w odpowiednie oświadczenia o zasadach SELinux. Dzięki temu może
znacznie przyspieszają programowanie SELinux.
Aby go użyć, uruchom:
adb pull /sys/fs/selinux/policy
adb logcat -b events -d | audit2allow -p policy
Należy jednak zachować ostrożność podczas sprawdzania każdego potencjalnego dodania
przekraczające uprawnienia. Na przykład w celu przesłania do aplikacji audit2allow
Wcześniejsza odmowa z powodu rmt_storage
skutkuje następującym wynikiem
sugerowana instrukcja zasad SELinux:
#============= shell ============== allow shell kernel:security setenforce; #============= rmt ============== allow rmt kmem_device:chr_file { read write };
Daje to usłudze rmt
możliwość zapisu pamięci jądra,
rzucił okiem na lukę w zabezpieczeniach. Często instrukcje audit2allow
są tylko punktem wyjścia. Po zastosowaniu oświadczeń może być konieczna zmiana
domeny źródłowej i etykiety celu oraz zastosuj odpowiednie
w celu opracowania odpowiednich zasad. Czasami badana odmowa musi
nie spowoduje żadnych zmian zasad; a nie aplikacji naruszającej zasady
należy zmienić.