Po zintegrowaniu podstawowego poziomu funkcjonalności SELinux i dokładnej analizie wyników możesz dodać własne ustawienia zasad, aby uwzględnić dostosowania systemu operacyjnego Android. Zasady te muszą nadal spełniać wymagania programu zgodności z systemem Android i nie mogą usuwać domyślnych ustawień SELinux.
Producenci nie powinni usuwać istniejących zasad SELinux. W przeciwnym razie ryzykują złamanie implementacji Androida SELinux i aplikacji, którymi zarządza. Obejmuje to aplikacje innych firm, które prawdopodobnie będą wymagały ulepszenia, aby były zgodne i funkcjonalne. Aplikacje nie mogą wymagać żadnych modyfikacji, aby nadal działać na urządzeniach obsługujących SELinux.
Rozpoczynając dostosowywanie SELinux, pamiętaj, aby:
- Napisz politykę SELinux dla wszystkich nowych demonów
- Jeśli to konieczne, używaj predefiniowanych domen
- Przypisz domenę do dowolnego procesu uruchomionego jako usługa
init
- Przed napisaniem polityki zapoznaj się z makrami
- Prześlij zmiany w podstawowych zasadach do AOSP
I pamiętaj, żeby nie:
- Utwórz niezgodną politykę
- Zezwalaj na dostosowywanie zasad użytkownika końcowego
- Zezwalaj na dostosowywanie zasad MDM
- Przestraszyć użytkowników naruszeniami zasad
- Dodaj tylne drzwi
Aby zapoznać się ze szczegółowymi wymaganiami, zobacz sekcję Funkcje zabezpieczeń jądra w dokumencie Definicja zgodności z systemem Android .
SELinux wykorzystuje podejście oparte na białej liście, co oznacza, że wszelki dostęp musi być wyraźnie dozwolony w zasadach, aby został przyznany. Ponieważ domyślna polityka SELinux Androida obsługuje już projekt Android Open Source, nie musisz w żaden sposób modyfikować ustawień SELinux. Jeśli dostosujesz ustawienia SELinuksa, zachowaj szczególną ostrożność, aby nie uszkodzić istniejących aplikacji. Rozpocząć:
- Użyj najnowszego jądra Androida .
- Przyjmij zasadę najmniejszych przywilejów .
- Adresuj tylko własne dodatki do Androida. Domyślna zasada automatycznie współpracuje z bazą kodu projektu Android Open Source .
- Podziel komponenty oprogramowania na moduły realizujące pojedyncze zadania.
- Utwórz zasady SELinux, które izolują te zadania od niepowiązanych funkcji.
- Umieść te zasady w plikach
*.te
(rozszerzenie plików źródłowych zasad SELinux) w katalogu/device/ manufacturer / device-name /sepolicy
i użyj zmiennychBOARD_SEPOLICY
, aby uwzględnić je w swojej kompilacji. - Początkowo zezwalaj na nowe domeny. Odbywa się to za pomocą deklaracji permisywnej w pliku
.te
domeny. - Analizuj wyniki i udoskonalaj definicje domen.
- Usuń deklarację permissive, gdy w kompilacjach debugowania użytkownika nie pojawiają się dalsze odmowy.
Po zintegrowaniu zmiany zasad SELinux dodaj krok do przepływu pracy programistycznej, aby zapewnić zgodność z SELinux w przyszłości. W idealnym procesie tworzenia oprogramowania polityka SELinux zmienia się tylko wtedy, gdy zmienia się model oprogramowania, a nie faktyczna implementacja.
Kiedy zaczniesz dostosowywać SELinux, najpierw sprawdź swoje dodatki do Androida. Jeśli dodano komponent realizujący nową funkcję, przed włączeniem trybu wymuszania upewnij się, że komponent jest zgodny z zasadami bezpieczeństwa systemu Android, a także wszelkimi powiązanymi zasadami opracowanymi przez producenta OEM.
Aby zapobiec niepotrzebnym problemom, lepiej być zbyt rozbudowanym i nadmiernie kompatybilnym niż zbyt restrykcyjnym i niekompatybilnym, co skutkuje uszkodzonymi funkcjami urządzenia. I odwrotnie, jeśli Twoje zmiany przyniosą korzyści innym, powinieneś przesłać modyfikacje do domyślnej polityki SELinux jako łatkę . Jeśli łatka zostanie zastosowana do domyślnej polityki bezpieczeństwa, nie będzie konieczne wprowadzanie tej zmiany w każdej nowej wersji Androida.
Przykładowe oświadczenia polityczne
SELinux opiera się na języku komputerowym M4 i dlatego obsługuje różnorodne makra, aby zaoszczędzić czas.
W poniższym przykładzie wszystkim domenom przyznano dostęp do odczytu i zapisu do /dev/null
oraz odczytu z /dev/zero
.
# Allow read / write access to /dev/null allow domain null_device:chr_file { getattr open read ioctl lock append write}; # Allow read-only access to /dev/zero allow domain zero_device:chr_file { getattr open read ioctl lock };
Tę samą instrukcję można zapisać za pomocą makr SELinux *_file_perms
(skrót):
# Allow read / write access to /dev/null allow domain null_device:chr_file rw_file_perms; # Allow read-only access to /dev/zero allow domain zero_device:chr_file r_file_perms;
Przykładowa polityka
Oto pełna przykładowa polityka DHCP, którą przeanalizujemy poniżej:
type dhcp, domain; permissive dhcp; type dhcp_exec, exec_type, file_type; type dhcp_data_file, file_type, data_file_type; init_daemon_domain(dhcp) net_domain(dhcp) allow dhcp self:capability { setgid setuid net_admin net_raw net_bind_service }; allow dhcp self:packet_socket create_socket_perms; allow dhcp self:netlink_route_socket { create_socket_perms nlmsg_write }; allow dhcp shell_exec:file rx_file_perms; allow dhcp system_file:file rx_file_perms; # For /proc/sys/net/ipv4/conf/*/promote_secondaries allow dhcp proc_net:file write; allow dhcp system_prop:property_service set ; unix_socket_connect(dhcp, property, init) type_transition dhcp system_data_file:{ dir file } dhcp_data_file; allow dhcp dhcp_data_file:dir create_dir_perms; allow dhcp dhcp_data_file:file create_file_perms; allow dhcp netd:fd use; allow dhcp netd:fifo_file rw_file_perms; allow dhcp netd:{ dgram_socket_class_set unix_stream_socket } { read write }; allow dhcp netd:{ netlink_kobject_uevent_socket netlink_route_socket netlink_nflog_socket } { read write };
Przeanalizujmy przykład:
W pierwszym wierszu deklaracji typu demon DHCP dziedziczy z podstawowej polityki bezpieczeństwa ( domain
). Z poprzednich przykładów instrukcji wynika, że DHCP może czytać i zapisywać do /dev/null
.
W drugim wierszu DHCP jest identyfikowane jako domena zezwalająca.
W wierszu init_daemon_domain(dhcp)
polityka stwierdza, że DHCP jest uruchamiany z init
i może się z nim komunikować.
W wierszu net_domain(dhcp)
zasada umożliwia DHCP korzystanie z typowych funkcji sieciowych domeny net
, takich jak odczytywanie i zapisywanie pakietów TCP, komunikacja przez gniazda i przeprowadzanie żądań DNS.
W linii allow dhcp proc_net:file write;
polityka stwierdza, że DHCP może zapisywać do określonych plików w /proc
. Ta linia demonstruje szczegółowe etykietowanie plików w SELinux. Używa etykiety proc_net
, aby ograniczyć dostęp do zapisu tylko do plików w katalogu /proc/sys/net
.
Ostatni blok przykładu rozpoczynający się od allow dhcp netd:fd use;
przedstawia, w jaki sposób aplikacje mogą współdziałać ze sobą. Polityka mówi, że DHCP i netd mogą komunikować się ze sobą za pośrednictwem deskryptorów plików, plików FIFO, gniazd datagramowych i gniazd strumieniowych UNIX. DHCP może jedynie odczytywać i zapisywać z gniazd datagramów i gniazd strumieni UNIX, a nie może ich tworzyć ani otwierać.
Dostępne elementy sterujące
Klasa | Pozwolenie |
---|---|
plik | ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename execute swapon quotaon mounton |
informator | add_name remove_name reparent search rmdir open audit_access execmod |
gniazdo elektryczne | ioctl read write create getattr setattr lock relabelfrom relabelto append bind connect listen accept getopt setopt shutdown recvfrom sendto recv_msg send_msg name_bind |
system plików | mount remount unmount getattr relabelfrom relabelto transition associate quotamod quotaget |
proces | fork transition sigchld sigkill sigstop signull signal ptrace getsched setsched getsession getpgid setpgid getcap setcap share getattr setexec setfscreate noatsecure siginh setrlimit rlimitinh dyntransition setcurrent execmem execstack execheap setkeycreate setsockcreate |
bezpieczeństwo | compute_av compute_create compute_member check_context load_policy compute_relabel compute_user setenforce setbool setsecparam setcheckreqprot read_policy |
zdolność | chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap |
WIĘCEJ | I WIĘCEJ |
zasady nigdy nie zezwalaj
Reguły SELinux neverallow
zabraniają zachowań, które nigdy nie powinny mieć miejsca. Dzięki testom zgodności reguły SELinux neverallow
są teraz egzekwowane na wszystkich urządzeniach.
Poniższe wytyczne mają pomóc producentom uniknąć błędów związanych z regułami neverallow
podczas dostosowywania. Zastosowane tutaj numery reguł odpowiadają systemowi Android 5.1 i mogą ulec zmianie w zależności od wydania.
Zasada 48: neverallow { domain -debuggerd -vold -dumpstate -system_server } self:capability sys_ptrace;
Zobacz stronę podręcznika dla ptrace
. Funkcja sys_ptrace
umożliwia ptrace
dowolnego procesu, co pozwala na dużą kontrolę nad innymi procesami i powinno należeć tylko do wyznaczonych komponentów systemu, opisanych w regule. Zapotrzebowanie na tę funkcję często wskazuje na obecność czegoś, co nie jest przeznaczone do kompilacji dostępnych dla użytkownika lub funkcjonalności, która nie jest potrzebna. Usuń niepotrzebny komponent.
Zasada 76: neverallow { domain -appdomain -dumpstate -shell -system_server -zygote } { file_type -system_file -exec_type }:file execute;
Zasada ta ma na celu uniemożliwienie wykonania dowolnego kodu w systemie. W szczególności zapewnia, że wykonywany jest tylko kod w /system
, co zapewnia gwarancję bezpieczeństwa dzięki mechanizmom takim jak zweryfikowany rozruch. Często najlepszym rozwiązaniem w przypadku problemu związanego z regułą neverallow
jest przeniesienie naruszającego kodu na partycję /system
.
Dostosowywanie SEPolicy w systemie Android 8.0+
W tej sekcji znajdują się wytyczne dotyczące zasad dostawcy SELinux w systemie Android 8.0 i nowszych wersjach, w tym szczegółowe informacje na temat rozszerzeń SEPolicy i SEPolicy Android Open Source Project (AOSP). Aby uzyskać więcej informacji o tym, jak zasady SELinux są utrzymywane w zgodności pomiędzy partycjami i wersjami Androida, zobacz Zgodność .
Umieszczenie polityki
W systemie Android 7.0 i wcześniejszych wersjach producenci urządzeń mogli dodać zasady do BOARD_SEPOLICY_DIRS
, w tym zasady mające na celu rozszerzenie zasad AOSP na różne typy urządzeń. W Androidzie 8.0 i nowszych dodanie zasad do BOARD_SEPOLICY_DIRS
powoduje umieszczenie zasad tylko w obrazie dostawcy.
W systemie Android 8.0 i nowszych zasadach istnieją następujące lokalizacje w AOSP:
- system/sepolicy/public . Obejmuje zasady wyeksportowane do użycia w zasadach specyficznych dla dostawcy. Wszystko trafia do infrastruktury kompatybilności z Androidem 8.0. Zasady publiczne mają obowiązywać w różnych wersjach, więc możesz uwzględnić wszystko
/public
w swoich dostosowanych zasadach. Z tego powodu typ zasad, które można umieścić w/public
jest bardziej ograniczony. Rozważ to wyeksportowany interfejs API zasad platformy: wszystko, co dotyczy interfejsu między/system
i/vendor
należy tutaj. - system/sepolicy/prywatny . Zawiera politykę niezbędną do funkcjonowania obrazu systemu, ale o której polityka dotycząca obrazu dostawcy nie powinna mieć wiedzy.
- system/sepolicy/sprzedawca . Zawiera zasady dotyczące komponentów, które znajdują się w
/vendor
, ale istnieją w drzewie platformy podstawowej (nie w katalogach specyficznych dla urządzenia). Jest to artefakt rozróżnienia w systemie kompilacji urządzeń i komponentów globalnych; koncepcyjnie jest to część opisanych poniżej zasad dotyczących konkretnego urządzenia. - urządzenie/ manufacturer / device-name /sepolicy . Zawiera zasady dotyczące konkretnego urządzenia. Obejmuje także dostosowanie zasad urządzenia do zasad, które w systemie Android 8.0 i nowszych wersjach odpowiadają zasadom dotyczącym komponentów na obrazie dostawcy.
W systemie Android 11 i nowszych partycjach system_ext i partycjach produktów mogą również zawierać zasady specyficzne dla partycji. zasady system_ext i zasady produktu są również podzielone na publiczne i prywatne, a dostawcy mogą używać polityk publicznych system_ext i produktu, takich jak zasady systemowe.
-
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS
. Zawiera zasady wyeksportowane do użycia w zasadach specyficznych dla dostawcy. Zainstalowany na partycji system_ext. -
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS
. Zawiera zasady niezbędne do funkcjonowania obrazu system_ext, ale o których zasadach dotyczących obrazów dostawcy nie powinni wiedzieć. Zainstalowany na partycji system_ext. -
PRODUCT_PUBLIC_SEPOLICY_DIRS
. Zawiera zasady wyeksportowane do użycia w zasadach specyficznych dla dostawcy. Zainstalowany na partycji produktu. -
PRODUCT_PRIVATE_SEPOLICY_DIRS
. Zawiera politykę niezbędną do funkcjonowania wizerunku produktu, ale o której polityka wizerunkowa dostawcy nie powinna mieć wiedzy. Zainstalowany na partycji produktu.
Obsługiwane scenariusze zasad
Na urządzeniach z systemem Android 8.0 lub nowszym obraz dostawcy musi współpracować z obrazem systemu OEM i referencyjnym obrazem systemu AOSP dostarczonym przez Google (i musi przejść CTS na tym obrazie referencyjnym). Wymagania te zapewniają czyste oddzielenie struktury od kodu dostawcy. Takie urządzenia obsługują następujące scenariusze.
rozszerzenia zawierające wyłącznie obrazy dostawcy
Przykład : dodanie nowej usługi do vndservicemanager
z obrazu dostawcy, która obsługuje procesy z obrazu dostawcy.
Podobnie jak w przypadku urządzeń uruchamianych z poprzednimi wersjami Androida, dodaj dostosowanie specyficzne dla urządzenia w device/ manufacturer / device-name /sepolicy
. Nowa polityka regulująca sposób, w jaki komponenty dostawcy wchodzą w interakcję z (tylko) innymi komponentami innych dostawców , powinna obejmować typy obecne tylko w device/ manufacturer / device-name /sepolicy
. Zapisane tutaj zasady pozwalają na działanie kodu dostawcy, nie będą aktualizowane w ramach OTA opartego wyłącznie na frameworku i będą obecne w połączonych zasadach na urządzeniu z referencyjnym obrazem systemu AOSP.
obsługa obrazu dostawcy do współpracy z AOSP
Przykład : Dodanie nowego procesu (zarejestrowanego w hwservicemanager
z obrazu dostawcy), który implementuje warstwę HAL zdefiniowaną przez AOSP.
Podobnie jak w przypadku urządzeń uruchamianych z poprzednimi wersjami Androida, wykonaj dostosowanie specyficzne dla urządzenia w device/ manufacturer / device-name /sepolicy
. Polityka wyeksportowana jako część system/sepolicy/public/
jest dostępna do użytku i jest dostarczana jako część polityki dostawcy. Typy i atrybuty z polityki publicznej mogą być używane w nowych regułach określających interakcje z nowymi bitami specyficznymi dla dostawcy, z zastrzeżeniem podanych ograniczeń neverallow
. Podobnie jak w przypadku dotyczącym wyłącznie dostawcy, nowe zasady nie zostaną zaktualizowane w ramach OTA opartego wyłącznie na platformie i będą obecne w połączonych zasadach na urządzeniu z referencyjnym obrazem systemu AOSP.
rozszerzenia zawierające wyłącznie obraz systemu
Przykład : Dodanie nowej usługi (zarejestrowanej w menedżerze usług), do której dostęp mają tylko inne procesy z obrazu systemu.
Dodaj tę politykę do system/sepolicy/private
. Możesz dodać dodatkowe procesy lub obiekty, aby włączyć funkcjonalność w obrazie systemu partnera, pod warunkiem, że te nowe bity nie muszą wchodzić w interakcję z nowymi komponentami w obrazie dostawcy (w szczególności takie procesy lub obiekty muszą w pełni funkcjonować bez zasad z obrazu dostawcy) . Polityka wyeksportowana przez system/sepolicy/public
jest dostępna tutaj, tak samo jak w przypadku rozszerzeń zawierających wyłącznie obrazy dostawcy. Ta polityka jest częścią obrazu systemu i może zostać zaktualizowana w ramach OTA opartego wyłącznie na frameworku, ale nie będzie obecna w przypadku korzystania z referencyjnego obrazu systemu AOSP.
rozszerzenia obrazu dostawcy, które obsługują rozszerzone komponenty AOSP
Przykład: nowa warstwa HAL inna niż AOSP do użytku przez rozszerzonych klientów, którzy również istnieją w obrazie systemu AOSP (np. rozszerzony serwer_systemowy).
Zasady interakcji pomiędzy systemem a dostawcą muszą być zawarte w katalogu device/ manufacturer / device-name /sepolicy
dostarczonym na partycji dostawcy. Jest to podobne do powyższego scenariusza dodania obsługi obrazu dostawcy do pracy z referencyjnym obrazem AOSP, z tą różnicą, że zmodyfikowane komponenty AOSP mogą również wymagać dodatkowych zasad, aby poprawnie działać z resztą partycji systemowej (co jest w porządku, o ile nadal mają publiczne etykiety typu AOSP).
Zasady interakcji publicznych komponentów AOSP z rozszerzeniami składającymi się wyłącznie z obrazu systemu powinny znajdować się w system/sepolicy/private
.
rozszerzenia obrazu systemu, które uzyskują dostęp tylko do interfejsów AOSP
Przykład: Nowy proces systemowy inny niż AOSP musi uzyskać dostęp do warstwy HAL, na której opiera się AOSP.
Jest to podobne do przykładu rozszerzenia zawierającego wyłącznie obraz systemu , z tą różnicą, że nowe komponenty systemu mogą wchodzić w interakcje w interfejsie system/vendor
. Polityka dla nowego komponentu systemu musi być umieszczona w system/sepolicy/private
, co jest akceptowalne pod warunkiem, że odbywa się poprzez interfejs już ustanowiony przez AOSP w system/sepolicy/public
(tj. są tam typy i atrybuty wymagane do funkcjonalności). Chociaż zasady mogłyby zostać uwzględnione w zasadach specyficznych dla urządzenia, nie mogłyby one używać innych typów system/sepolicy/private
ani zmieniać się (w jakikolwiek sposób wpływający na zasady) w wyniku aktualizacji obejmującej wyłącznie platformę. Polityka może zostać zmieniona w OTA opartym wyłącznie na frameworku, ale nie będzie obecna podczas korzystania z obrazu systemu AOSP (który również nie będzie zawierał nowego komponentu systemu).
rozszerzenia obrazu dostawcy, które obsługują nowe komponenty systemu
Przykład: dodanie nowej warstwy HAL innej niż AOSP do wykorzystania przez proces klienta bez analogu AOSP (a zatem wymaga własnej domeny).
Podobnie jak w przykładzie rozszerzeń AOSP , polityka dotycząca interakcji pomiędzy systemem a dostawcą musi znajdować się w katalogu device/ manufacturer / device-name /sepolicy
dostarczonym na partycji dostawcy (aby mieć pewność, że polityka systemowa nie zawiera informacji o szczegółach specyficznych dla dostawcy). Możesz dodać nowe typy publiczne, które rozszerzają politykę w system/sepolicy/public
; należy to zrobić jedynie jako dodatek do istniejącej polityki AOSP, tj. nie usuwać polityki publicznej AOSP. Nowe typy publiczne można następnie wykorzystać w politykach w system/sepolicy/private
i w device/ manufacturer / device-name /sepolicy
.
Należy pamiętać, że każdy dodatek do system/sepolicy/public
zwiększa złożoność, ujawniając nową gwarancję kompatybilności, którą należy śledzić w pliku mapowania i która podlega innym ograniczeniom. W system/sepolicy/public
można dodawać tylko nowe typy i odpowiadające im reguły zezwalające; atrybuty i inne instrukcje zasad nie są obsługiwane. Ponadto nowych typów publicznych nie można używać do bezpośredniego etykietowania obiektów w zasadach /vendor
.
Nieobsługiwane scenariusze zasad
Urządzenia uruchamiane z systemem Android 8.0 i nowszym nie obsługują poniższego scenariusza i przykładów zasad.
Dodatkowe rozszerzenia obrazu systemu, które wymagają uprawnień do nowych komponentów obrazu dostawcy po OTA wyłącznie w ramach platformy
Przykład: w następnej wersji Androida dodano nowy proces systemowy inny niż AOSP, wymagający własnej domeny, i potrzebuje dostępu do nowej warstwy HAL innej niż AOSP.
Podobnie jak w przypadku interakcji nowego systemu (innego niż AOSP) i komponentów dostawcy , z tą różnicą, że nowy typ systemu jest wprowadzony w OTA opartym wyłącznie na frameworku. Chociaż nowy typ można dodać do zasad w system/sepolicy/public
, istniejąca polityka dostawcy nie ma wiedzy o nowym typie, ponieważ śledzi tylko zasady publiczne systemu Android 8.0. AOSP radzi sobie z tym poprzez eksponowanie zasobów dostarczonych przez dostawcę poprzez atrybut (np. atrybut hal_foo
), ale ponieważ rozszerzenia partnerów atrybutów nie są obsługiwane w system/sepolicy/public
, ta metoda jest niedostępna dla zasad dostawcy. Dostęp musi być zapewniony przez istniejący wcześniej typ publiczny.
Przykład: zmiana w procesie systemowym (AOSP lub inny niż AOSP) musi zmienić sposób jego interakcji z nowym komponentem dostawcy innego niż AOSP.
Zasady dotyczące obrazu systemu muszą zostać napisane bez znajomości dostosowań określonych dostawców. Polityka dotycząca określonych interfejsów w AOSP jest zatem ujawniana poprzez atrybuty w systemie/sepolicy/public, dzięki czemu polityka dostawcy może wyrazić zgodę na przyszłą politykę systemową, która używa tych atrybutów. Jednak rozszerzenia atrybutów w system/sepolicy/public
nie są obsługiwane , więc wszystkie zasady określające sposób interakcji komponentów systemu z komponentami nowego dostawcy (i które nie są obsługiwane przez atrybuty już obecne w AOSP system/sepolicy/public
) muszą znajdować się w device/ manufacturer / device-name /sepolicy
. Oznacza to, że typy systemów nie mogą zmieniać dostępu dozwolonego dla typów dostawców w ramach OTA opartego wyłącznie na platformie.