SELinux ma ustawione domyślne odmowa dostępu, co oznacza, że każdy dostęp który ma zaczep w jądrze, musi być wyraźnie dozwolony przez zasadę. Ten oznacza, że plik zasad zawiera dużą ilość informacji na temat reguły, typy, zajęcia, uprawnienia i nie tylko. Pełna analiza SELinux wykracza poza zakres tego dokumentu, ale zrozumienie sposobu pisania reguł zasad jest teraz niezbędne przy wprowadzaniu nowych urządzeń z Androidem. W internecie można znaleźć wiele informacji na temat SELinux. Patrz sekcja Pomoc techniczna dokumentacji z sugerowanymi materiałami.
Pliki kluczy
Aby włączyć SELinux, zintegruj najnowsze jądro Androida, a potem dodaj pliki znajdujące się w katalogu system/sepolicy. Po skompilowaniu te pliki stanowią zabezpieczenia jądra SELinux i obejmują starsze wersje systemu operacyjnego Android.
Ogólnie nie należy modyfikować plików system/sepolicy
bezpośrednio. Zamiast tego dodaj lub zmodyfikuj własne pliki zasad dotyczących urządzeń w katalogu /device/manufacturer/device-name/sepolicy
. W Androidzie 8.0 i nowszych zmiany wprowadzane w tych plikach powinny
mają wpływ tylko na zasady
w katalogu dostawcy. Więcej informacji o oddzielaniu publicznych zasad SEPolicy w Androidzie 8.0 i nowszych znajdziesz w artykule Dostosowywanie SEPolicy w Androidzie 8.0 i nowszych wersjach. Niezależnie od wersji Androida nadal modyfikujesz te pliki:
Pliki zasad
Pliki z końcówką *.te
to pliki źródłowe zasad SELinux,
definiowanie domen i ich etykiet. Może być konieczne utworzenie nowych plików zasad w
/device/manufacturer/device-name/sepolicy
,
ale staraj się aktualizować istniejące pliki, gdy tylko jest to możliwe.
Pliki kontekstu
W plikach kontekstowych określasz etykiety swoich obiektów.
file_contexts
przypisuje etykiety do plików i jest używany przez różne komponentów przestrzeni użytkownika. Podczas tworzenia nowych zasad utwórz lub zaktualizuj ten plik, aby przypisać do plików nowe etykiety. Aby zastosować nowąfile_contexts
, ponownie utworzyć obraz systemu plików lub uruchomićrestorecon
dla pliku, zmienić etykiety. Podczas przekształcania zmiany wfile_contexts
są automatycznie stosowane do partycji systemowej i partycji danych użytkownika w ramach przekształcania. Zmiany można też automatycznie stosować podczas uaktualniania innych partycji, dodając do pliku init.board.rc wywołaniarestorecon_recursive
po zamontowaniu partycji do odczytu i zapisu.genfs_contexts
przypisuje etykiety do systemów plików, takich jakproc
lubvfat
, które nie obsługują rozszerzonych połączeń . Ta konfiguracja jest wczytywana jako część zasady jądra, ale zmiany mogą nie zadziałać w przypadku izorów w rdzeniu, wymagając ponownego uruchomienia lub odłącz i ponownie podłącz system plików, aby w pełni zastosować zmianę. Określone etykiety mogą być też przypisane do konkretnych uchwytów, takich jakvfat
, za pomocą opcjicontext=mount
.property_contexts
przypisuje etykiety właściwościom systemu Android, aby kontrolować, które procesy mogą je ustawiać. Ta konfiguracja jest odczytywana przez Procesinit
podczas uruchamiania.service_contexts
przypisuje etykiety usługom bindera Androida, aby kontrolować, które procesy mogą dodawać (rejestrować) i znajdować (wyszukiwać) odwołanie bindera dla usługi. Ta konfiguracja jest odczytywana przez processervicemanager
podczas uruchamiania.seapp_contexts
przypisuje etykiety do procesów aplikacji i katalogów/data/data
. Ta konfiguracja jest odczytywana przez proceszygote
przy każdym uruchomieniu aplikacji oraz przezinstalld
podczas uruchamiania.mac_permissions.xml
przypisuje tagseinfo
do aplikacji na podstawie ich sygnatury i opcjonalnie nazwy pakietu. Tagseinfo
może być następnie używany jako klucz wseapp_contexts
, aby przypisać określoną etykietę do wszystkich aplikacji z ten tagseinfo
. Ta konfiguracja jest odczytywana przezsystem_server
podczas uruchamiania.keystore2_key_contexts
przypisuje etykiety do przestrzeni nazw Keystore 2.0. Te przestrzenie nazw są wymuszane przez demona keystore2. Keystore zawsze udostępniał przestrzenie nazw na podstawie identyfikatorów UID/AID. Keystore 2.0 dodatkowo wymusza przestrzenie nazw zdefiniowane w pliku sepolicy. Szczegółowy opis formatu i konwencji znajdziesz tutaj.
Plik Makefile BoardConfig.mk
Po zmodyfikowaniu lub dodaniu plików zasad i kontekstu zaktualizuj plik /device/manufacturer/device-name/BoardConfig.mk
makefile, aby odwoływał się do podkatalogu sepolicy
i każdego nowego pliku zasad.
Więcej informacji na temat zmiennych BOARD_SEPOLICY
znajdziesz tutaj:
system/sepolicy/README
.
BOARD_SEPOLICY_DIRS += \ <root>/device/manufacturer/device-name/sepolicy BOARD_SEPOLICY_UNION += \ genfs_contexts \ file_contexts \ sepolicy.te
Po przebudowaniu SELinux jest włączony na urządzeniu. Możesz teraz dostosować zasady SELinux, aby uwzględnić własne dodatki do systemu operacyjnego Android zgodnie z opisem w sekcji Personalizacja, lub zweryfikować istniejące ustawienia zgodnie z opisem w sekcji Weryfikacja.
Gdy nowe pliki zasad i aktualizacje pliku BoardConfig.mk zostaną zainstalowane, nowe ustawienia zasad zostaną automatycznie wbudowane w końcowy plik zasad jądra. Więcej informacji na temat tworzenia zasad Sepolicy na urządzeniu znajdziesz w sekcji Sepolicy tworzenia zasad.
Implementacja
Aby rozpocząć korzystanie z SELinux:
- Włącz SELinux w jądrze:
CONFIG_SECURITY_SELINUX=y
- Zmień parametr kernel_cmdline lub polecenie startconfig tak, aby:
BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
lubBOARD_BOOTCONFIG := androidboot.selinux=permissive
Służy tylko do wstępnego opracowywania zasad na urządzeniu. Po masz początkową zasadę wczytywania, usuń ten parametr, jest egzekwowane lub przestaje działać CTS. - Uruchom system w trybie mniej rygorystycznym i sprawdź, jakie odmowy pojawiają się podczas uruchamiania:
W systemie Ubuntu 14.04 lub nowszym:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
W systemie Ubuntu 12.04:adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- Oceń wyniki pod kątem ostrzeżeń podobnych do
init: Warning! Service name needs a SELinux domain defined; please fix!
Zobacz Weryfikacja instrukcji i narzędziami. - Zidentyfikuj urządzenia i inne nowe pliki, które wymagają etykiet.
- Użyj istniejących lub nowych etykiet dla obiektów. Przejrzyj pliki
*_contexts
, aby sprawdzić, jak były wcześniej etykietowane, i przypisz nową etykietę, znając znaczenie poprzedniej. Najlepiej, istniejąca etykieta, która jest zgodna z naszymi zasadami, ale czasami potrzebujesz nowej etykiety, a reguły dostępu do niej są niezbędną. Dodaj etykiety do odpowiednich plików kontekstowych. - Określ domeny/procesy, które powinny mieć własne domeny zabezpieczeń.
Prawdopodobnie musisz napisać dla każdej z nich zupełnie nowe zasady. Wszystkie usługi utworzone na podstawie usługi
init
powinny mieć własne. Te polecenia pomogą Ci znaleźć usługi, które nadal działają (ale WSZYSTKIE usługi wymagają takiej obsługi):
adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
- Sprawdź
init.device.rc
, aby zidentyfikować domeny, które nie mają typu domeny. Udostępnij im domenę wcześniej w programowania, aby uniknąć dodawania reguł doinit
lub myląc dostępinit
z tymi, które są w ich do własnych zasad. - Aby używać zmiennych
BOARD_SEPOLICY_*
, skonfigurujBOARD_CONFIG.mk
. Zobacz README (w języku angielskim) wsystem/sepolicy
, aby dowiedzieć się, jak to skonfigurować. - Sprawdź pliki init.device.rc i fstab.device i upewnij się, że każde użycie opcji
mount
odpowiada poprawnie oznaczonemu systemowi plików lub że określono opcjęcontext= mount
. - Przejrzyj każdą odmowę i utwórz zasadę SELinux, która będzie obsługiwać każdą z nich. Zobacz przykłady w sekcji Dostosowywanie.
Zacznij od zasad podanych w AOSP, a następnie na ich podstawie na własne potrzeby. Więcej informacji o strategii dotyczącej zasad dokładniej przyjrzeć się niektórym z tych kroków, zobacz Zapisywanie zasad SELinux.
Przykłady zastosowań
Oto kilka przykładów luk w zabezpieczeniach, które warto wziąć pod uwagę podczas tworzenia własnych treści i powiązane zasady SELinux:
Dowiązania symboliczne: dowiązania symboliczne są wyświetlane jako pliki, dlatego często są
i odczytać je jako pliki, co może prowadzić do ataku. Na przykład niektóre komponenty uprzywilejowane, takie jak init
, zmieniają uprawnienia niektórych plików, czasami w nadmierny sposób.
Osoby przeprowadzające atak mogą zastąpić te pliki dowiązaniami symbolicznymi do kontrolowanego przez nich kodu. co pozwoli atakującym zastąpić dowolne pliki. Jeśli jednak wiesz, aplikacja nigdy nie przechodzi dowiązania symbolicznego, możesz tego zabronić z SELinux.
Pliki systemowe: weź pod uwagę klasę plików systemowych, które
powinna być modyfikowana tylko przez serwer systemu. Mimo to, ponieważ netd
,
init
i vold
działają jako root, mają dostęp do tych plików systemowych. Jeśli netd
zostanie naruszony, może to spowodować utratę tych plików i potencjalnie samego serwera systemu.
Dzięki SELinux możesz zidentyfikować te pliki jako pliki danych serwera systemowego.
Dlatego jedyną domeną, która ma do nich dostęp tylko do odczytu i zapisu, jest serwer systemowy.
Nawet jeśli netd
zostanie naruszony, nie będzie można przełączyć domen na domenę serwera systemowego i uzyskać dostępu do tych plików systemowych, mimo że działa on jako root.
Dane aplikacji: kolejnym przykładem jest klasa funkcji, które muszą działać jako root, ale nie powinny mieć dostępu do danych aplikacji. To niesamowite, przydatne, ponieważ mogą być zgłaszane asercje o szerokim zakresie, na przykład określone domeny niepowiązane do danych aplikacji, które nie mają dostępu do internetu.
setattr: w przypadku poleceń takich jak chmod
czy
chown
, możesz zidentyfikować zbiór plików, w których powiązane
domena może przeprowadzić setattr
. Wszystko inne może być zabronione, nawet przez użytkownika root. Aplikacja może więc działać na podstawie reguł chmod
i chown
, ale nie shell_data_files
ani system_data_files
.