Na tej stronie dowiesz się, jak tworzone są zasady SELinux. Zasady SELinux są tworzone na podstawie połączenia podstawowych zasad AOSP (platformy) i zasad dotyczących konkretnego urządzenia (dostawcy). Proces tworzenia zasad SELinux w Androidzie 4.4–7.0 polegał na scalaniu wszystkich fragmentów sepolicy, a następnie generowaniu monolitycznych plików w katalogu głównym. Oznaczało to, że dostawcy układów SOC i producenci ODM modyfikowali boot.img (w przypadku urządzeń innych niż A/B) lub system.img (w przypadku urządzeń A/B) za każdym razem, gdy zmieniano zasady.
W Androidzie 8.0 i nowszym zasady platformy i dostawcy są tworzone oddzielnie.
Producenci układów SoC i OEM mogą aktualizować swoje części zasad, tworzyć obrazy (np. vendor.img i boot.img), a następnie aktualizować te obrazy niezależnie od aktualizacji platformy.
Jednak ponieważ modułowe pliki zasad SELinux są przechowywane na partycjach /vendor, proces init musi wcześniej zamontować partycje system i vendor, aby móc odczytać z nich pliki SELinux i połączyć je z podstawowymi plikami SELinux w katalogu system (przed załadowaniem ich do jądra).
Pliki źródłowe
Logika tworzenia SELinux znajduje się w tych plikach:
-
external/selinux: zewnętrzny projekt SELinux, używany do tworzenia narzędzi wiersza poleceń HOST do kompilowania zasad i etykiet SELinux.-
external/selinux/libselinux: Android używa tylko podzbioru zewnętrznego projektulibselinuxwraz z pewnymi dostosowaniami specyficznymi dla Androida. Więcej informacji znajdziesz w sekcjiexternal/selinux/README.android. -
external/selinux/libsepol: -
external/selinux/checkpolicy: kompilator zasad SELinux (pliki wykonywalne hosta:checkpolicy,checkmoduleidispol). Zależy odlibsepol.
-
-
system/sepolicy: podstawowe konfiguracje zasad SELinux w Androidzie, w tym konteksty i pliki zasad. Znajduje się tu też główna logika kompilacji sepolicy (system/sepolicy/Android.mk).
Więcej informacji o plikach w system/sepolicy znajdziesz w artykule Pliki kluczy.
Android 7.x i starsze
W tej sekcji opisujemy, jak tworzone są zasady SELinux w Androidzie 7.x i starszych wersjach.
Proces kompilacji w przypadku Androida 7.x i starszych wersji
Zasady SELinux są tworzone przez połączenie podstawowych zasad AOSP z dostosowaniami specyficznymi dla urządzenia. Połączone zasady są następnie przekazywane do kompilatora zasad i różnych narzędzi sprawdzających. Dostosowywanie do konkretnego urządzenia odbywa się za pomocą zmiennej BOARD_SEPOLICY_DIRS zdefiniowanej w pliku Boardconfig.mk. Ta globalna zmienna kompilacji zawiera listę katalogów, które określają kolejność wyszukiwania dodatkowych plików zasad.
Na przykład dostawca układu SoC i producent ODM mogą dodać po jednym katalogu – jeden na potrzeby ustawień specyficznych dla układu SoC, a drugi na potrzeby ustawień specyficznych dla urządzenia – aby wygenerować ostateczne konfiguracje SELinux dla danego urządzenia:
BOARD_SEPOLICY_DIRS += device/SoC/common/sepolicyBOARD_SEPOLICY_DIRS += device/SoC/DEVICE/sepolicy
Zawartość plików file_contexts w system/sepolicy i BOARD_SEPOLICY_DIRS jest łączona w celu wygenerowania file_contexts.bin na urządzeniu:

Rysunek 1. Logika kompilacji SELinux.
Plik sepolicy składa się z kilku plików źródłowych:
- Zwykły tekst
policy.confjest generowany przez połączenie w kolejności:security_classes,initial_sids,*.te,genfs_contextsiport_contexts. - Zawartość każdego pliku (np.
security_classes) jest połączeniem plików o tej samej nazwie w katalogachsystem/sepolicy/iBOARDS_SEPOLICY_DIRS. policy.confjest wysyłany do kompilatora SELinux w celu sprawdzenia składni i kompilowany do formatu binarnego jakosepolicyna urządzeniu.
Rysunek 2. plik zasad SELinux,
Pliki SELinux
Po skompilowaniu urządzenia z Androidem 7.x i starszym zwykle zawierają te pliki związane z SELinux:
selinux_versionsepolicy: dane binarne po połączeniu plików zasad (np.security_classes,initial_sidsi*.te)file_contextsproperty_contextsseapp_contextsservice_contextssystem/etc/mac_permissions.xml
Więcej informacji znajdziesz w artykule Implementowanie SELinux.
Inicjalizacja SELinux
Po uruchomieniu systemu SELinux działa w trybie zezwalającym (a nie w trybie egzekwowania). Proces inicjowania wykonuje te zadania:
- Wczytuje
sepolicyplików z dysku RAM do jądra za pomocą/sys/fs/selinux/load. - Przełącza SELinux w tryb egzekwowania.
- Uruchamia
re-exec(), aby zastosować do siebie regułę domeny SELinux.
Aby skrócić czas rozruchu, jak najszybciej wykonaj proces re-exec()init.
Android 8.0 lub nowszy
W Androidzie 8.0 zasady SELinux są podzielone na komponenty platformy i dostawcy, co umożliwia niezależne aktualizowanie zasad platformy i dostawcy przy zachowaniu zgodności.
Zasady platformy sepolicy są dodatkowo podzielone na części prywatną i publiczną, aby eksportować określone typy i atrybuty do osób piszących zasady dostawców. Gwarantujemy, że publiczne typy i atrybuty platformy będą utrzymywane jako stabilne interfejsy API w przypadku danej wersji platformy. Zgodność z poprzednimi typami/atrybutami publicznymi platformy można zagwarantować w przypadku kilku wersji za pomocą plików mapowania platformy.
Proces kompilacji w Androidzie 8.0
Zasady SELinux w Androidzie 8.0 powstają przez połączenie fragmentów z /system i /vendor. Logika prawidłowego konfigurowania tej funkcji znajduje się w
/platform/system/sepolicy/Android.bp.
Zasady te obowiązują w tych lokalizacjach:
| Lokalizacja | Zawiera |
|---|---|
system/sepolicy/public |
Platform sepolicy API |
system/sepolicy/private |
Szczegóły implementacji platformy (dostawcy mogą je zignorować) |
system/sepolicy/vendor |
Pliki zasad i kontekstu, których dostawcy mogą używać (dostawcy mogą je zignorować) |
BOARD_SEPOLICY_DIRS |
Vendor sepolicy |
BOARD_ODM_SEPOLICY_DIRS (Android 9 lub nowszy) |
ODM sepolicy |
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 lub nowszy) |
system_ext sepolicy API |
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 lub nowszy) |
system_ext szczegóły implementacji (dostawcy mogą je zignorować); |
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 lub nowszy) |
Product sepolicy API |
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 lub nowszy) |
Szczegóły implementacji produktu (dostawcy mogą je zignorować) |
System kompilacji pobiera te zasady i tworzy komponenty zasad system, system_ext, product, vendor i odm w odpowiedniej partycji. Kroki obejmują:
- Przekonwertuj zasady na format SELinux Common Intermediate Language (CIL), a w szczególności:
- Zasady dotyczące platform publicznych (
system,system_ext,product) - Połączona polityka prywatności i polityka publiczna
- Zasady publiczne, zasady dostawcy i zasady
BOARD_SEPOLICY_DIRS
- Zasady dotyczące platform publicznych (
- Wersja zasad udostępnionych publicznie w ramach zasad dostawcy.
Wykorzystaj utworzone publiczne zasady CIL, aby określić, które części połączonych publicznych zasad oraz zasad dostawcy i
BOARD_SEPOLICY_DIRSmuszą zostać przekształcone w atrybuty połączone z zasadami platformy. - Utwórz plik mapowania, który łączy platformę i części sprzedawcy. Początkowo łączy ona tylko typy z zasad publicznych z odpowiednimi atrybutami w zasadach dostawcy. Później stanowi też podstawę pliku utrzymywanego w przyszłych wersjach platformy, co umożliwia zgodność z zasadami dostawcy kierowanymi na tę wersję platformy.
- Łączenie plików zasad (opis rozwiązań na urządzeniu i wstępnie skompilowanych).
- Połącz zasady dotyczące mapowania, platformy i dostawców.
- Skompiluj wyjściowy plik binarny zasad.
Zasady platformy dotyczące bezpieczeństwa
Publiczna zasada SEPolicy platformy obejmuje wszystko, co jest zdefiniowane w sekcji
system/sepolicy/public. Platforma może założyć, że typy i atrybuty zdefiniowane w ramach zasad publicznych są stabilnymi interfejsami API dla danej wersji platformy. Stanowi to część zasad bezpieczeństwa, która jest eksportowana przez platformę, na której deweloperzy zasad dostawcy (czyli urządzenia) mogą pisać dodatkowe zasady dotyczące konkretnego urządzenia.
Typy są wersjonowane zgodnie z wersją zasad, w odniesieniu do której pisane są pliki dostawcy, zdefiniowaną przez zmienną kompilacji PLATFORM_SEPOLICY_VERSION. Wersja zasad publicznych jest następnie dołączana do zasad dostawcy i (w oryginalnej formie) do zasad platformy. W związku z tym ostateczne zasady obejmują zasady platformy prywatnej, publiczne zasady bezpieczeństwa bieżącej platformy, zasady dotyczące urządzenia i wersjonowane zasady publiczne odpowiadające wersji platformy, na podstawie której zostały opracowane zasady urządzenia.
Platform private sepolicy
Prywatne zasady bezpieczeństwa platformy obejmują wszystko, co zostało zdefiniowane w sekcji
/system/sepolicy/private. Ta część zasad zawiera typy, uprawnienia i atrybuty wymagane do działania platformy. Nie są one eksportowane do dostawców ani autorów zasad dotyczących urządzeń. Osoby piszące zasady spoza platformy nie mogą tworzyć rozszerzeń zasad na podstawie typów, atrybutów i reguł zdefiniowanych w prywatnych zasadach bezpieczeństwa platformy. Ponadto te reguły można modyfikować lub mogą one zniknąć w ramach aktualizacji samego frameworka.
Mapowanie prywatne platformy
Prywatne mapowanie platformy obejmuje oświadczenia o zasadach, które mapują atrybuty udostępniane w publicznych zasadach platformy w poprzednich wersjach platformy na konkretne typy używane w bieżących publicznych zasadach platformy sepolicy. Dzięki temu zasady dostawcy, które zostały napisane na podstawie publicznych atrybutów platformy z poprzednich wersji publicznych zasad bezpieczeństwa platformy, nadal działają. Wersja jest określana na podstawie zmiennej kompilacji PLATFORM_SEPOLICY_VERSION ustawionej w AOSP dla danej wersji platformy. Dla każdej poprzedniej wersji platformy, z której ta platforma ma akceptować zasady dostawcy, istnieje oddzielny plik mapowania. Więcej informacji znajdziesz w artykule Zgodność zasad.
Android 11 lub nowszy
Z tej sekcji dowiesz się, jak tworzone są zasady SELinux w Androidzie 11 i nowszym.
zasady zabezpieczeń system_ext i product
W Androidzie 11 dodano zasady system_ext i product. Podobnie jak w przypadku zasad platformy, zasady system_ext i product są podzielone na zasady publiczne i prywatne.
Zasady publiczne są eksportowane do dostawcy. Typy i atrybuty stają się stabilnym interfejsem API, a zasady dostawcy mogą odwoływać się do typów i atrybutów w zasadach publicznych. Typy są wersjonowane zgodnie z PLATFORM_SEPOLICY_VERSION, a wersjonowane zasady są uwzględniane w zasadach dostawcy. Pierwotne zasady są uwzględnione w każdej z sekcji system_ext i product.
Zasady ochrony prywatności zawierają typy, uprawnienia i atrybuty wymagane tylko w przypadku system_ext i tylko w przypadku product, które są niezbędne do działania funkcji podziału na system_ext i product.
Zasady prywatności są niewidoczne dla dostawcy, co oznacza, że te reguły są wewnętrzne i można je modyfikować.
mapowanie system_ext i product;
system_ext i product mogą eksportować wyznaczone typy publiczne do dostawcy. Każdy partner jest jednak odpowiedzialny za zachowanie zgodności. Aby zapewnić zgodność, partnerzy mogą udostępniać własne pliki mapowania, które mapują atrybuty z wersjami z poprzednich wersji na konkretne typy używane w bieżącej publicznej wersji sepolicy:
- Aby zainstalować plik mapowania dla
system_ext, umieść plik CIL zawierający odpowiednie informacje o mapowaniu w{SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil, a następnie dodajsystem_ext_{ver}.cildoPRODUCT_PACKAGES. - Aby zainstalować plik mapowania dla
product, umieść plik CIL zawierający odpowiednie informacje o mapowaniu w{PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil, a następnie dodajproduct_{ver}.cildoPRODUCT_PACKAGES.
Zapoznaj się z przykładem, który dodaje plik mapowania partycji product urządzenia Redbull.
Wstępnie skompilowane zasady SELinux
Zanim init włączy SELinux, init zbiera wszystkie pliki CIL z partycji (system, system_ext, product, vendor i odm) i kompiluje je w zasady binarne, czyli format, który można wczytać do jądra. Ponieważ kompilacja zajmuje trochę czasu (zwykle 1–2 sekundy), pliki CIL są wstępnie kompilowane w czasie kompilacji i umieszczane w /vendor/etc/selinux/precompiled_sepolicy lub /odm/etc/selinux/precompiled_sepolicy wraz z hashami sha256 wejściowych plików CIL. W czasie działania init sprawdza, czy któryś z plików zasad został zaktualizowany, porównując hasze. Jeśli nic się nie zmieniło, init wczytuje wstępnie skompilowane zasady. Jeśli nie, init kompiluje go na bieżąco i używa zamiast wstępnie skompilowanego.
W szczególności wstępnie skompilowane zasady są używane, jeśli spełnione są wszystkie te warunki: W tym przypadku
{partition} oznacza partycję, w której znajduje się wstępnie skompilowana zasada: vendor lub odm.
- Oba elementy
/system/etc/selinux/plat_sepolicy_and_mapping.sha256i/{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256istnieją i są identyczne. - Nie istnieją ani
/system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256, ani/{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256. lub oba istnieją i są identyczne. - Nie istnieją ani
/product/etc/selinux/product_sepolicy_and_mapping.sha256, ani/{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256. lub oba istnieją i są identyczne.
Jeśli któraś z nich się różni, init wraca do ścieżki kompilacji na urządzeniu. Więcej informacji znajdziesz w sekcji
system/core/init/selinux.cpp.