Weryfikuję SELinux

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 we właściwym miejscu , uruchamiając polecenie getenforce.

Powoduje to wydrukowanie globalnego trybu SELinux: wymuszania lub mniej rygorystycznego. Do dla każdej domeny musisz sprawdzić odpowiednie lub uruchom najnowszą wersję sepolicy-analyze z odpowiednia flaga (-p) znajduje się w /platform/system/sepolicy/tools/.

Odmowy czytania

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ć dane wyjściowe SELinux na tych urządzeniach i przesłać je do systemu dmesg. dopracować ustawienia przed opublikowaniem ich w trybie mniej rygorystycznym w trybie wymuszania. Komunikaty dziennika SELinux zawierają fragment avc:, więc może można ją łatwo znaleźć za pomocą usługi grep. Można przechwytywać trwające logi odmowy przez uruchomienie cat /proc/kmsg lub przechwytywanie logów odmowy z poprzedniego uruchomienia przez uruchomienie 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 zobaczysz wszystkie istotne wiadomości, możesz wyłączyć tę opcję uruchamiając adb shell auditctl -r 0.

Na podstawie tych danych producenci mogą łatwo określić, czy użytkownicy systemu Naruszają zasadę SELinux. Producenci mogą później naprawić może to być niewłaściwe działanie ze względu na zmiany w oprogramowaniu, zasady SELinux lub jedno i drugie.

Komunikaty te wskazują w szczególności, których procesów nie będzie można wykonać 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. Razem z tclass na końcu (unix_stream_socket), mówi mniej więcej o tym, co zostało zrobione do czego. W tym przypadku coś próbowało połączyć się z gniazdem strumienia w systemie Unix.
  • scontext (u:r:shell:s0) informuje, w jakim kontekście zainicjowano działanie. W w tym przypadku system 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 do netd.
  • Element comm="ping" na górze zawiera dodatkową wskazówkę dotyczącą uruchamianych w momencie wygenerowania odmowy. W tym przypadku jest to całkiem dobra wskazówka.

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óbowana czynność jest wyróżniona w nawiasie. read write lub setenforce.
  • Użytkownik, który wykonał czynność – wpis scontext (kontekst źródła) reprezentuje aktora, w tym przypadku demona rmt_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 działania względem obiektu, w tym przypadku chr_file (urządzenia do obsługi znaków).

Zrzut stosu użytkownika i stosów jądra

W niektórych przypadkach informacje zawarte w dzienniku zdarzeń nie wystarczą do zidentyfikowania źródło zaprzeczania. Często warto zebrać łańcuch wywołań, w tym jądro przestrzeni użytkownika, aby lepiej zrozumieć, dlaczego nastąpiła odmowa.

Ostatnie jądra tworzą 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. android12-5.4 gałąź jest również obsługiwana. 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.

Przechwytywanie łańcucha wywołań

Pierwszym krokiem jest zarejestrowanie zdarzenia za pomocą usługi 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 odmowę. Po zakończeniu nagrywania można zatrzymać. W tym przykładzie przy użyciu funkcji Ctrl-c próbka powinna zostać przechwycona:

^Csimpleperf I cmd_record.cpp:751] Samples recorded: 1. Samples lost: 0.

Na koniec można użyć simpleperf report do sprawdzenia przechwyconego zrzutu 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

Przechodzę na tryb mniej rygorystyczny

Egzekwowanie SELinux można wyłączyć przez ADB podczas debugowania użytkownika lub kompilacji angielskiej. Aby to zrobić: Najpierw przełącz ADB na roota, uruchamiając adb root. Następnie, aby wyłączyć SELinux, egzekwowanie, uruchom:

adb shell setenforce 0

W wierszu poleceń jądra (podczas wcześniejszego wywołania urządzenia):

androidboot.selinux=permissive
androidboot.selinux=enforcing

Na Androidzie 12 możesz to zrobić za pomocą konfiguracji rozruchowej:

androidboot.selinux=permissive
androidboot.selinux=enforcing

Korzystanie z Audit2allow

Narzędzie audit2allow przyjmuje dmesg odmów i konwertuje je na odpowiednie instrukcje zasad 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: 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 i punktu początkowego. 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ć.