SELinux jest ustawiony na domyślną odmowę, co oznacza, że każdy dostęp, na który ma hak w jądrze, musi być wyraźnie dozwolony przez politykę. Oznacza to, że plik zasad składa się z dużej ilości informacji dotyczących reguł, typów, klas, uprawnień i nie tylko. Pełne omówienie SELinux wykracza poza zakres tego dokumentu, ale zrozumienie sposobu pisania reguł polityki jest teraz niezbędne przy wprowadzaniu nowych urządzeń z Androidem. Dostępnych jest już wiele informacji na temat SELinuksa. Zobacz dokumentację pomocniczą , aby zapoznać się z sugerowanymi zasobami.
Kluczowe pliki
Aby włączyć SELinux, zintegruj najnowsze jądro Androida , a następnie dołącz pliki znajdujące się w katalogu system/sepolicy . Po skompilowaniu pliki te obejmują politykę bezpieczeństwa jądra SELinux i obejmują nadrzędny system operacyjny Android.
Ogólnie rzecz biorąc, nie należy bezpośrednio modyfikować plików system/sepolicy
. Zamiast tego dodaj lub edytuj własne pliki zasad specyficzne dla urządzenia w katalogu /device/ manufacturer / device-name /sepolicy
. W Androidzie 8.0 i nowszych zmiany wprowadzone w tych plikach powinny mieć wpływ tylko na zasady w katalogu dostawców. Aby uzyskać więcej informacji na temat oddzielenia polityki publicznej w systemie Android 8.0 i nowszych, zobacz Dostosowywanie SEPolicy w systemie Android 8.0 lub nowszym . Niezależnie od wersji Androida nadal modyfikujesz te pliki:
Pliki zasad
Pliki kończące się na *.te
to pliki źródłowe zasad SELinux, które definiują domeny i ich etykiety. Może być konieczne utworzenie nowych plików zasad w /device/ manufacturer / device-name /sepolicy
, ale jeśli to możliwe, powinieneś spróbować zaktualizować istniejące pliki.
Pliki kontekstowe
Pliki kontekstowe służą do określania etykiet obiektów.
-
file_contexts
przypisuje etykiety do plików i jest używany przez różne komponenty przestrzeni użytkownika. Podczas tworzenia nowych zasad utwórz lub zaktualizuj ten plik, aby przypisać nowe etykiety do plików. Aby zastosować nowyfile_contexts
, odbuduj obraz systemu plików lub uruchomrestorecon
na pliku, którego etykieta ma zostać zmieniona. Podczas aktualizacji zmiany wfile_contexts
są automatycznie stosowane do partycji systemowych i danych użytkownika w ramach aktualizacji. Zmiany można również automatycznie zastosować podczas aktualizacji na inne partycje, dodając wywołaniarestorecon_recursive
do pliku init. board plik .rc 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 atrybutów. Ta konfiguracja jest ładowana jako część polityki jądra, ale zmiany mogą nie zostać uwzględnione w przypadku i-węzłów w rdzeniu, co wymaga ponownego uruchomienia komputera lub odmontowania i ponownego zamontowania systemu plików, aby w pełni zastosować zmiany. Określone etykiety mogą być również przypisane do konkretnych montowań, np.vfat
przy użyciu opcjicontext=mount
. -
property_contexts
przypisuje etykiety do właściwości systemu Android, aby kontrolować, jakie procesy mogą je ustawiać. Konfiguracja ta jest odczytywana przez procesinit
podczas uruchamiania. -
service_contexts
przypisuje etykiety do usług segregatorów systemu Android, aby kontrolować, jakie procesy mogą dodawać (rejestrować) i znajdować (wyszukiwać) odniesienia do segregatorów dla usługi. Konfiguracja ta jest odczytywana przez processervicemanager
podczas uruchamiania. -
seapp_contexts
przypisuje etykiety procesom aplikacji i katalogom/data/data
. Ta konfiguracja jest odczytywana przez proceszygote
przy każdym uruchomieniu aplikacji iinstalld
podczas uruchamiania. -
mac_permissions.xml
przypisuje znacznikseinfo
do aplikacji na podstawie ich podpisu i opcjonalnie nazwy pakietu. Znacznikseinfo
może następnie zostać użyty jako klucz w plikuseapp_contexts
w celu przypisania określonej etykiety do wszystkich aplikacji z tym znacznikiemseinfo
. 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. Magazyn kluczy zawsze udostępniał przestrzenie nazw oparte na UID/AID. Magazyn kluczy 2.0 dodatkowo wymusza przestrzenie nazw zdefiniowane przez sepolicy. Szczegółowy opis formatu i konwencji tego pliku można znaleźć tutaj .
Plik Makefile BoardConfig.mk
Po edycji lub dodaniu plików zasad i kontekstu zaktualizuj plik makefile /device/ manufacturer / device-name /BoardConfig.mk
aby odwoływał się do podkatalogu sepolicy
i każdego nowego pliku polityki. Więcej informacji na temat zmiennych BOARD_SEPOLICY
można znaleźć w pliku system/sepolicy/README
.
BOARD_SEPOLICY_DIRS += \ <root>/device/manufacturer/device-name/sepolicy BOARD_SEPOLICY_UNION += \ genfs_contexts \ file_contexts \ sepolicy.te
Po przebudowaniu na Twoim urządzeniu jest włączony SELinux. Możesz teraz dostosować zasady SELinux, aby uwzględnić własne dodatki do systemu operacyjnego Android, zgodnie z opisem w sekcji Dostosowywanie , lub zweryfikować istniejącą konfigurację zgodnie z opisem w sekcji Walidacja .
Po zainstalowaniu nowych plików zasad i aktualizacji BoardConfig.mk nowe ustawienia zasad zostaną automatycznie wbudowane w ostateczny plik zasad jądra. Aby uzyskać więcej informacji na temat tworzenia sepolicy na urządzeniu, zobacz Tworzenie sepolicy .
Realizacja
Aby rozpocząć pracę z SELinuxem:
- Włącz SELinux w jądrze:
CONFIG_SECURITY_SELINUX=y
- Zmień parametr kernel_cmdline lub bootconfig tak, aby:
BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
lubBOARD_BOOTCONFIG := androidboot.selinux=permissive
To służy tylko do wstępnego opracowania polityki dla urządzenia. Po ustaleniu początkowej zasady ładowania początkowego usuń ten parametr, aby urządzenie egzekwowało zasady, w przeciwnym razie CTS nie powiedzie się. - Uruchom system w trybie zezwalającym i zobacz, jakie odmowy występują 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ń wynik pod kątem ostrzeżeń przypominających
init: Warning! Service name needs a SELinux domain defined; please fix!
Zobacz Walidacja , aby uzyskać instrukcje i narzędzia. - Identyfikuj urządzenia i inne nowe pliki wymagające etykietowania.
- Użyj istniejących lub nowych etykiet dla swoich obiektów. Przejrzyj pliki
*_contexts
, aby zobaczyć, jak rzeczy były wcześniej oznaczone, i wykorzystaj wiedzę o znaczeniu etykiet, aby przypisać nowe. W idealnym przypadku będzie to istniejąca etykieta, która będzie pasować do polityki, ale czasami potrzebna będzie nowa etykieta i zasady dostępu do tej etykiety. Dodaj etykiety do odpowiednich plików kontekstowych. - Zidentyfikuj domeny/procesy, które powinny mieć własne domeny zabezpieczeń. Prawdopodobnie będziesz musiał napisać dla każdego z nich zupełnie nową polisę. Na przykład wszystkie usługi zrodzone z
init
powinny mieć własne. Poniższe polecenia pomagają odkryć te, które pozostają uruchomione (ale WSZYSTKIE usługi wymagają takiego traktowania):adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
- Przejrzyj
init. device .rc
aby zidentyfikować domeny, które nie mają typu domeny. Daj im domenę na początku procesu programowania, aby uniknąć dodawania reguł doinit
lub w inny sposób mylenia dostępuinit
z tymi, które są w ich własnych zasadach. - Skonfiguruj
BOARD_CONFIG.mk
tak, aby używał zmiennychBOARD_SEPOLICY_*
. Zobacz README wsystem/sepolicy
aby uzyskać szczegółowe informacje na temat konfiguracji. - Sprawdź init. device .rc i fstab. device i upewnij się, że każde użycie
mount
odpowiada odpowiednio oznaczonemu systemowi plików lub że określono opcjęcontext= mount
. - Przejrzyj każdą odmowę i utwórz politykę SELinux, aby prawidłowo obsłużyć każdą odmowę. Zobacz przykłady w Dostosowywanie .
Powinieneś zacząć od zasad w AOSP, a następnie wykorzystać je do własnych dostosowań. Aby uzyskać więcej informacji na temat strategii polityki i bliżej przyjrzeć się niektórym z tych kroków, zobacz Pisanie polityki SELinux .
Przypadków użycia
Oto konkretne przykłady exploitów, które należy wziąć pod uwagę podczas tworzenia własnego oprogramowania i powiązanych zasad SELinux:
Dowiązania symboliczne — ponieważ dowiązania symboliczne pojawiają się w postaci plików, często są odczytywane jako pliki, co może prowadzić do exploitów. Na przykład niektóre uprzywilejowane komponenty, takie jak init
, zmieniają uprawnienia niektórych plików, czasami powodując ich nadmierne otwarcie.
Osoby atakujące mogą następnie zastąpić te pliki dowiązaniami symbolicznymi do kontrolowanego przez siebie kodu, umożliwiając osobie atakującej zastąpienie dowolnych plików. Ale jeśli wiesz, że Twoja aplikacja nigdy nie przejdzie przez dowiązanie symboliczne, możesz zabronić jej tego w SELinux.
Pliki systemowe — rozważ klasę plików systemowych, które powinny być modyfikowane tylko przez serwer systemowy. Mimo to, ponieważ netd
, init
i vold
działają jako root, mogą uzyskać dostęp do tych plików systemowych. Jeśli więc netd
zostanie naruszony, może zagrozić tym plikom i potencjalnie samemu serwerowi systemowemu.
Dzięki SELinux możesz zidentyfikować te pliki jako pliki danych serwera systemowego. Dlatego jedyną domeną, która ma do nich dostęp do odczytu/zapisu, jest serwer systemowy. Nawet jeśli netd
zostałby naruszony, nie mógłby przełączyć domen na domenę serwera systemowego i uzyskać dostępu do plików systemowych, mimo że działa jako root.
Dane aplikacji — innym przykładem jest klasa funkcji, które muszą działać jako root, ale nie powinny mieć dostępu do danych aplikacji. Jest to niezwykle przydatne, ponieważ można sformułować szerokie twierdzenia, na przykład zakaz dostępu do Internetu dla niektórych domen niezwiązanych z danymi aplikacji.
setattr — w przypadku poleceń takich jak chmod
i chown
można zidentyfikować zestaw plików, w których powiązana domena może wykonać setattr
. Wszystko poza tym może być zabronione w przypadku tych zmian, nawet przez rootowanie. Zatem aplikacja może uruchomić chmod
i chown
względem plików oznaczonych jako app_data_files
, ale nie shell_data_files
lub system_data_files
.