Po zintegrowaniu podstawowego poziomu funkcjonalności SELinux i dokładnym przeanalizowaniu wyników, możesz dodać własne ustawienia zasad, aby uwzględnić dostosowania w systemie operacyjnym 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ącej polityki SELinux. W przeciwnym razie ryzykują złamanie implementacji Android 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 działały. Aplikacje nie mogą wymagać żadnych modyfikacji, aby mogły 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
- W razie potrzeby używaj predefiniowanych domen
- Przypisz domenę do dowolnego procesu powstałego jako usługa
init
- Zapoznaj się z makrami przed napisaniem zasad
- Prześlij zmiany do podstawowych zasad do AOSP
I pamiętaj, aby 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
Szczegółowe wymagania można znaleźć w sekcji Funkcje zabezpieczeń jądra w dokumencie Definicja zgodności z systemem Android .
SELinux korzysta z białej listy, co oznacza, że wszelki dostęp musi być wyraźnie dozwolony w polityce, aby mógł zostać przyznany. Ponieważ domyślna polityka SELinux systemu Android obsługuje już projekt Android Open Source Project, nie musisz w żaden sposób modyfikować ustawień SELinux. Jeśli dostosujesz ustawienia SELinux, bardzo uważaj, aby nie uszkodzić istniejących aplikacji. Zaczynać:
- Użyj najnowszego jądra Androida .
- Przyjmij zasadę najmniejszych przywilejów .
- Adresuj tylko własne dodatki do Androida. Domyślne zasady działają automatycznie z bazą kodu Android Open Source Project .
- Podziel komponenty oprogramowania na moduły, które wykonują pojedyncze zadania.
- Twórz polityki 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 zezwalającej w pliku
.te
domeny. - Analizuj wyniki i udoskonalaj definicje swojej domeny.
- Usuń deklarację permisywną, gdy w kompilacjach userdebug nie pojawią się kolejne odmowy.
Po zintegrowaniu zmian w polityce 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 rzeczywista implementacja.
Gdy zaczniesz dostosowywać SELinux, najpierw skontroluj swoje dodatki do Androida. Jeśli dodano składnik, który wykonuje nową funkcję, przed włączeniem trybu wymuszania upewnij się, że składnik jest zgodny z zasadami zabezpieczeń systemu Android, a także ze wszystkimi powiązanymi zasadami utworzonymi przez producenta OEM.
Aby zapobiec niepotrzebnym problemom, lepiej być zbyt obszernym i nadmiernie kompatybilnym niż zbyt restrykcyjnym i niekompatybilnym, co skutkuje uszkodzeniem funkcji 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 poprawka zostanie zastosowana do domyślnych zasad zabezpieczeń, nie będzie trzeba wprowadzać tej zmiany w każdym nowym wydaniu systemu Android.
Przykładowe oświadczenia dotyczące zasad
SELinux jest oparty na języku komputerowym M4 i dlatego obsługuje różne makra, aby zaoszczędzić czas.
W poniższym przykładzie wszystkim domenom przyznano dostęp do odczytu lub zapisu do /dev/null
i 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 };
To samo stwierdzenie można napisać 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ładowe zasady
Oto pełna przykładowa polityka DHCP, którą zbadamy 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 deklaracja typu, demon DHCP dziedziczy z podstawowej polityki bezpieczeństwa ( domain
). Z poprzednich przykładów instrukcji, DHCP może odczytywać i zapisywać do /dev/null
.
W drugim wierszu DHCP jest identyfikowany jako domena zezwalająca.
W wierszu init_daemon_domain(dhcp)
zasady określają, że DHCP jest generowany z init
i może się z nim komunikować.
W net_domain(dhcp)
zasady umożliwiają DHCP korzystanie z typowych funkcji sieciowych z domeny net
, takich jak odczytywanie i zapisywanie pakietów TCP, komunikacja przez gniazda i wykonywanie żądań DNS.
W wierszu allow dhcp proc_net:file write;
zasady określają, że DHCP może zapisywać do określonych plików w /proc
. Ta linia pokazuje drobnoziarniste etykietowanie plików SELinux. Używa etykiety proc_net
, aby ograniczyć dostęp do zapisu tylko do plików w /proc/sys/net
.
Ostatni blok przykładu zaczynający się od allow dhcp netd:fd use;
przedstawia, w jaki sposób aplikacje mogą komunikować się 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 tylko odczytywać i zapisywać z gniazd datagramowych i gniazd strumieniowych UNIX i nie może ich tworzyć ani otwierać.
Dostępne sterowanie
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 |
JESZCZE | I WIĘCEJ |
Nigdy nie zezwalaj na zasady
Reguły neverallow
SELinux zabraniają zachowania, które nigdy nie powinno mieć miejsca. Dzięki testom zgodności , reguły neverallow
SELinux są teraz egzekwowane na wszystkich urządzeniach.
Poniższe wskazówki mają na celu pomóc producentom uniknąć błędów związanych z regułami neverallow
podczas dostosowywania. Użyte 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ę man dla ptrace
. Zdolność sys_ptrace
daje możliwość ptrace
dowolnego procesu, co pozwala na dużą kontrolę nad innymi procesami i powinno należeć tylko do wyznaczonych komponentów systemu, określonych w regule. Potrzeba tej możliwości często wskazuje na obecność czegoś, co nie jest przeznaczone do kompilacji dostępnych dla użytkownika lub funkcji, które nie są potrzebne. Usuń niepotrzebny składnik.
Zasada 76: neverallow { domain -appdomain -dumpstate -shell -system_server -zygote } { file_type -system_file -exec_type }:file execute;
Ta reguła ma na celu uniemożliwienie wykonania dowolnego kodu w systemie. W szczególności zapewnia, że wykonywany jest tylko kod w /system
, co zapewnia gwarancje bezpieczeństwa dzięki mechanizmom takim jak zweryfikowany rozruch. Często najlepszym rozwiązaniem w przypadku napotkania problemu z regułą neverallow
jest przeniesienie nieprawidłowego kodu na partycję /system
.
Dostosowywanie SEPolicy w systemie Android 8.0+
Ta sekcja zawiera wytyczne dotyczące zasad dostawcy SELinux w systemie Android 8.0 i nowszych, w tym szczegółowe informacje na temat rozszerzeń SEPolicy i SEPolicy Android Open Source Project (AOSP). Aby uzyskać więcej informacji na temat zachowania zgodności zasad SELinux na różnych partycjach i wersjach systemu Android, zobacz Zgodność .
Umieszczenie polisy
W Androidzie 7.0 i wcześniejszych producenci urządzeń mogli dodać zasady do BOARD_SEPOLICY_DIRS
, w tym zasady mające na celu rozszerzenie zasad AOSP na różnych typach urządzeń. W systemie Android 8.0 i nowszych dodanie zasad do BOARD_SEPOLICY_DIRS
powoduje umieszczenie zasad tylko w obrazie dostawcy.
W systemie Android 8.0 i nowszych zasady istnieją w następujących lokalizacjach w AOSP:
- system/sepolityka/publiczny . 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 wydaniach, dzięki czemu możesz uwzględnić dowolny element
/public
w swoich dostosowanych zasadach. Z tego powodu typ polityki, który można umieścić w/public
, jest bardziej ograniczony. Weź pod uwagę interfejs API eksportowanych zasad platformy: wszystko, co dotyczy interfejsu między/system
i/vendor
, należy tutaj. - system/sepolityka/prywatne . Obejmuje politykę niezbędną do funkcjonowania obrazu systemu, ale o której polityce obrazu dostawcy nie należy wiedzieć.
- system/sepolityka/dostawca . Zawiera zasady dotyczące komponentów, które znajdują się w katalogu
/vendor
, ale istnieją w drzewie platformy podstawowej (nie w katalogach specyficznych dla urządzenia). Jest to artefakt rozróżnienia w systemie budowania na urządzenia i komponenty globalne; koncepcyjnie jest to część zasad dotyczących konkretnych urządzeń opisanych poniżej. - urządzenie/ manufacturer / device-name /sepolicy . Obejmuje zasady specyficzne dla urządzenia. Obejmuje również dostosowania urządzeń do zasad, które w systemie Android 8.0 i nowszych odpowiadają zasadom dotyczącym składników w obrazie dostawcy.
W systemie Android 11 i nowszych partycje system_ext i produktu mogą również zawierać zasady specyficzne dla partycji. system_ext i polityki produktu są również podzielone na publiczne i prywatne, a dostawcy mogą korzystać z publicznych polityk system_ext i produktu, takich jak polityka systemowa.
-
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS
. Obejmuje zasady wyeksportowane do użycia w zasadach specyficznych dla dostawcy. Zainstalowany na partycji system_ext. -
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS
. Obejmuje politykę niezbędną do funkcjonowania obrazu system_ext, ale o której polityce obrazu dostawcy nie należy wiedzieć. Zainstalowany na partycji system_ext. -
PRODUCT_PUBLIC_SEPOLICY_DIRS
. Obejmuje zasady wyeksportowane do użycia w zasadach specyficznych dla dostawcy. Zainstalowany na partycji produktu. -
PRODUCT_PRIVATE_SEPOLICY_DIRS
. Obejmuje 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 polityki
Na urządzeniach uruchamianych 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 przekazać CTS do tego obrazu referencyjnego). Te wymagania zapewniają czysty rozdział między strukturą a kodem dostawcy. Takie urządzenia obsługują następujące scenariusze.
rozszerzenia tylko z obrazem 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 dostosowania specyficzne dla urządzenia w device/ manufacturer / device-name /sepolicy
. Nowa polityka regulująca interakcję komponentów dostawcy z (tylko) innymi komponentami dostawcy powinna obejmować typy obecne tylko w device/ manufacturer / device-name /sepolicy
. Zasady napisane w tym miejscu umożliwiają działanie kodu dostawcy, nie będą aktualizowane w ramach OTA tylko w ramach platformy i będą obecne w połączonych zasadach na urządzeniu z referencyjnym obrazem systemu AOSP.
obsługa obrazu dostawcy do 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, dostosuj specyficzne dla urządzenia w device/ manufacturer / device-name /sepolicy
. Zasady wyeksportowane jako część system/sepolicy/public/
są dostępne do użytku i są wysyłane jako część zasad dostawcy. Typy i atrybuty z polityki publicznej mogą być używane w nowych regułach dyktujących interakcje z nowymi bitami specyficznymi dla dostawcy, z zastrzeżeniem podanych ograniczeń neverallow
. Podobnie jak w przypadku tylko dostawcy, nowa zasada nie zostanie tutaj zaktualizowana jako część OTA tylko dla struktury i będzie obecna w połączonych zasadach na urządzeniu z referencyjnym obrazem systemu AOSP.
rozszerzenia tylko do obrazu systemu
Przykład : Dodanie nowej usługi (zarejestrowanej w servicemanager), do której dostęp mają tylko inne procesy z obrazu systemu.
Dodaj tę zasadę do system/sepolicy/private
. Możesz dodać dodatkowe procesy lub obiekty, aby włączyć funkcje w obrazie systemu partnera, pod warunkiem, że te nowe bity nie muszą wchodzić w interakcje z nowymi komponentami w obrazie dostawcy (w szczególności takie procesy lub obiekty muszą w pełni działać bez zasad z obrazu dostawcy) . Polityka eksportowana przez system/sepolicy/public
jest dostępna tutaj, tak jak w przypadku rozszerzeń zawierających tylko obraz dostawcy. Ta zasada jest częścią obrazu systemu i może być aktualizowana tylko w ramach OTA, ale nie będzie obecna podczas korzystania z referencyjnego obrazu systemu AOSP.
rozszerzenia obrazu dostawcy, które obsługują rozszerzone komponenty AOSP
Przykład: nowa warstwa HAL nie należąca do AOSP do użytku przez rozszerzonych klientów, którzy również istnieją w obrazie systemu AOSP (na przykład rozszerzony serwer_system).
Zasady interakcji mię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 dodawania obsługi obrazu dostawcy do pracy z referencyjnym obrazem AOSP, z wyjątkiem tego, ż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 posiadają publiczne etykiety typu AOSP).
Zasady interakcji publicznych komponentów AOSP z rozszerzeniami system-image-only powinny znajdować się w system/sepolicy/private
.
rozszerzenia obrazu systemu, które mają 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 tylko obraz systemu , z wyjątkiem tego, że nowe składniki systemu mogą wchodzić w interakcje w interfejsie system/vendor
. Polityka dla nowego komponentu systemu musi być umieszczona w system/sepolicy/private
, co jest dopuszczalne pod warunkiem, że odbywa się za pośrednictwem interfejsu już ustanowionego przez AOSP w system/sepolicy/public
(tj. są tam typy i atrybuty wymagane dla funkcjonalności). Chociaż zasady mogą być uwzględnione w zasadach dotyczących poszczególnych urządzeń, nie będą one w stanie używać innych typów system/sepolicy/private
ani zmieniać (w jakikolwiek sposób mający wpływ na zasady) w wyniku aktualizacji tylko dla struktury. Zasady mogą zostać zmienione w OTA tylko dla frameworka, ale nie będą obecne podczas korzystania z obrazu systemu AOSP (który również nie będzie zawierał nowego składnika systemu).
rozszerzenia obrazu dostawcy, które obsługują nowe komponenty systemu
Przykład: Dodanie nowej warstwy HAL innej niż AOSP do użytku przez proces klienta bez analogu AOSP (a zatem wymaga własnej domeny).
Podobnie jak w przykładzie z rozszerzeniami AOSP , zasady interakcji między systemem a dostawcą muszą znajdować się w katalogu device/ manufacturer / device-name /sepolicy
dostarczonym na partycji dostawcy (aby zapewnić, że zasady systemowe nie znają szczegółów specyficznych dla dostawcy). Możesz dodać nowe typy publiczne, które rozszerzają politykę w system/sepolicy/public
; należy to zrobić tylko w uzupełnieniu istniejącej polityki AOSP, tj. nie usuwać polityki publicznej AOSP. Nowe typy publiczne mogą być następnie używane do tworzenia zasad w system/sepolicy/private
oraz 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ę zgodnoś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 deklaracje 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 polityki
Urządzenia uruchamiane z systemem Android 8.0 lub nowszym nie obsługują następującego scenariusza zasad i przykładów.
Dodatkowe rozszerzenia do obrazu systemu, które wymagają uprawnień do nowych składników obrazu dostawcy po OTA tylko dla frameworka
Przykład: nowy proces systemowy inny niż AOSP, który wymaga własnej domeny, jest dodawany w następnej wersji systemu Android i wymaga dostępu do nowej warstwy HAL innej niż AOSP.
Podobna do interakcji nowego systemu (nie AOSP) i komponentów dostawcy , z wyjątkiem tego, że nowy typ systemu jest wprowadzany w OTA tylko dla frameworka. Chociaż nowy typ można dodać do zasad w system/sepolicy/public
, istniejąca zasada dostawcy nie ma wiedzy o nowym typie, ponieważ śledzi tylko zasady publiczne systemu Android 8.0. AOSP radzi sobie z tym, ujawniając zasoby dostarczone przez dostawcę za pomocą atrybutu (np. atrybutu hal_foo
), ale ponieważ rozszerzenia partnera 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 innym niż AOSP) musi zmienić sposób jego interakcji z nowym komponentem dostawcy innym niż AOSP.
Zasady dotyczące obrazu systemu muszą być napisane bez znajomości konkretnych dostosowań dostawcy. Polityka dotycząca określonych interfejsów w AOSP jest zatem ujawniana za pośrednictwem atrybutów w system/sepolicy/public, dzięki czemu polityka dostawcy może wyrazić zgodę na przyszłą politykę systemową, która korzysta z 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 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 tylko w ramach platformy.