Dostosowywanie SELinuksa

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 podstawowej polityce 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ąć:

  1. Użyj najnowszego jądra Androida .
  2. Przyjmij zasadę najmniejszych przywilejów .
  3. Adresuj tylko własne dodatki do Androida. Domyślna zasada automatycznie współpracuje z bazą kodu projektu Android Open Source .
  4. Podziel komponenty oprogramowania na moduły realizujące pojedyncze zadania.
  5. Utwórz zasady SELinux, które izolują te zadania od niepowiązanych funkcji.
  6. Umieść te zasady w plikach *.te (rozszerzenie plików źródłowych zasad SELinux) w katalogu /device/ manufacturer / device-name /sepolicy i użyj zmiennych BOARD_SEPOLICY , aby uwzględnić je w swojej kompilacji.
  7. Początkowo zezwalaj na nowe domeny. Odbywa się to za pomocą deklaracji permisywnej w pliku .te domeny.
  8. Analizuj wyniki i udoskonalaj definicje domen.
  9. 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 . Możliwość 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 . Zawiera 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.
Uwaga: gdy używany jest GSI, partycje system_ext OEM i partycje produktu nie zostaną zamontowane. Reguły w polityce dostawcy korzystające z systemu OEM i polityki publicznej produktu stają się NOP, ponieważ brakuje definicji typów specyficznych dla OEM.
Uwaga: Zachowaj szczególną ostrożność podczas korzystania z system_ext i polityk publicznych produktów. Zasady publiczne działają jako eksportowany interfejs API między rozszerzenie_systemu/produkt i dostawca. Partnerzy powinni sami zarządzać problemami ze zgodnością.

Obsługiwane scenariusze zasad

Na urządzeniach z systemem Android 8.0 i 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, dokonaj dostosowania dla konkretnego urządzenia w zakładce 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.