Dostosowywanie SELinux

Po zintegrowaniu podstawowej funkcji SELinux i dokładnej analizy wyników możesz dodać własne ustawienia zasad, aby uwzględnić swoje modyfikacje systemu operacyjnego Android. Te zasady muszą spełniać wymagania programu zgodności z Androidem i nie mogą usuwać domyślnych ustawień SELinux.

Producenci nie powinni usuwać istniejących zasad SELinux. W przeciwnym razie istnieje ryzyko uszkodzenia implementacji SELinux na Androidzie i aplikacji, które ona kontroluje. Dotyczy to aplikacji innych firm, które prawdopodobnie będą wymagać ulepszenia, aby spełniały wymagania i działały prawidłowo. Aplikacje nie mogą wymagać modyfikacji, aby nadal działać na urządzeniach z SELinux.

Podczas dostosowywania SELinux pamiętaj o tych kwestiach:

  • zapisać zasadę SELinux dla wszystkich nowych demonów.
  • W razie potrzeby używaj zdefiniowanych wstępnie domen
  • Przypisywanie domeny do dowolnego procesu utworzonego jako usługa init
  • Zanim zaczniesz pisać zasady, zapoznaj się z makrami
  • Przesyłanie zmian zasad podstawowych do AOSP

Pamiętaj, aby nie:

  • Tworzenie niezgodnych zasad
  • Zezwalanie na dostosowywanie zasad dla użytkowników
  • Zezwalanie na dostosowywanie zasad MDM
  • Straszenie użytkowników naruszeniem zasad
  • Dodawanie backdoorów

Szczegółowe wymagania znajdziesz w sekcji Funkcje zabezpieczeń jądra dokumentu definicji zgodności Androida.

SELinux używa podejścia z białą listą, co oznacza, że aby przyznać dostęp, należy wyraźnie zezwolić na niego w zasadach. Domyślna polityka SELinux na Androidzie obsługuje już projekt Android Open Source, więc nie musisz w żaden sposób modyfikować ustawień SELinux. Jeśli dostosowywujesz ustawienia SELinux, uważaj, aby nie zepsuć dotychczasowych aplikacji. Aby rozpocząć:

  1. Użyj najnowszej wersji jądra Androida.
  2. Stosuj zasadę minimalnego wymaganego poziomu uprawnień.
  3. Dotyczy to tylko Twoich własnych dodatków do Androida. Domyślna zasada działa automatycznie z kodem źródłowym Android Open Source Project.
  4. Podział komponentów oprogramowania na moduły, które wykonują pojedyncze zadania.
  5. Utwórz zasady SELinux, które izolują te zadania od funkcji niezwiązanych.
  6. Umieść te zasady w plikach *.te (rozszerzenie dla 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 kompilacji.
  7. Ustaw nowe domeny jako domyślnie dozwolone. W tym celu należy użyć deklaracji zezwalającej w pliku .te domeny.
  8. Przeanalizuj wyniki i udoskonal definicje domen.
  9. Usuń deklarację zezwalającą, gdy w kompilacji userdebug nie pojawią się żadne kolejne odmowy.

Po zintegrowaniu zmiany w zasadach SELinux dodaj do procesu programowania krok, który zapewni zgodność z SELinux w przyszłości. W idealnym procesie rozwoju oprogramowania zasady SELinux zmieniają się tylko wtedy, gdy zmienia się model oprogramowania, a nie jego rzeczywista implementacja.

Zanim zaczniesz dostosowywać SELinux, najpierw sprawdź swoje dodatki do Androida. Jeśli dodasz komponent, który wykonuje nową funkcję, przed włączeniem trybu wymuszania upewnij się, że spełnia on zasady bezpieczeństwa Androida oraz wszelkie powiązane zasady opracowane przez producenta OEM.

Aby uniknąć niepotrzebnych problemów, lepiej jest zastosować zbyt szerokie i zbyt zgodne ustawienia niż zbyt restrykcyjne i niezgodne, które powodują nieprawidłowe działanie urządzenia. Jeśli jednak zmiany przyniosą korzyści innym użytkownikom, prześlij modyfikacje do domyślnych zasad SELinux jako łatka. Jeśli poprawka zostanie zastosowana do domyślnej zasady zabezpieczeń, nie będzie trzeba wprowadzać tej zmiany przy każdej nowej wersji Androida.

Przykładowe oświadczenia

SELinux opiera się na języku komputerowym M4, dlatego obsługuje różne makra, aby zaoszczędzić czas.

W tym przykładzie wszystkim domenom przyznawane są uprawnienia do odczytu z domeny /dev/null i do zapisu do niej oraz do odczytu z domeny /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 polecenie można zapisać za pomocą makro 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 zasada

Poniżej znajdziesz przykładowe pełne zasady DHCP:

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 };

Przyjrzyjmy się temu przykładowi:

W pierwszym wierszu, deklaracji typu, demon DHCP dziedziczy z podstawowych zasad zabezpieczeń (domain). Z poprzednich przykładów stwierdzeń wynika, że DHCP może odczytywać i zapisywać dane w /dev/null.

W drugim wierszu DHCP jest zidentyfikowany jako domena zezwalająca.

W wierszu init_daemon_domain(dhcp) zasada określa, że DHCP jest tworzony przez init i może się z nim komunikować.

W wierszu net_domain(dhcp) zasada zezwala DHCP na korzystanie z funkcji sieci wspólnej z domeny net, takich jak odczyt i zapisywanie pakietów TCP, komunikacja przez gniazda i przesyłanie zapytań DNS.

W wierszu allow dhcp proc_net:file write; zasada określa, że DHCP może zapisywać dane w określonych plikach w folderze /proc. Ten wiersz pokazuje szczegółowe etykietowanie plików przez SELinux. Używa on etykiety proc_net, aby ograniczyć uprawnienia do zapisu tylko do plików w /proc/sys/net.

Ostatni blok przykładu, zaczynający się od allow dhcp netd:fd use;, pokazuje, jak aplikacje mogą ze sobą współdziałać. Polityka mówi, że DHCP i netd mogą komunikować się ze sobą za pomocą deskryptorów plików, plików FIFO, gniazd datagramowych i gniazd strumieniowych UNIX. DHCP może tylko odczytywać i zapisywać dane do gniazda datagramów i gniazda przesyłania strumieniowego UNIX, a nie tworzyć ani otwierać tych gniazd.

Dostępne ustawienia

Kategoria Uprawnienia
file
ioctl read write create getattr setattr lock relabelfrom relabelto append
unlink link rename execute swapon quotaon mounton
katalog
add_name remove_name reparent search rmdir open audit_access execmod
gniazdo
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
filesystem
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
zabezpieczenia
compute_av compute_create compute_member check_context load_policy
compute_relabel compute_user setenforce setbool setsecparam setcheckreqprot
read_policy
możliwości
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 WIELE WIĘCEJ

reguły neverallow

Reguły SELinux neverallow zabraniają zachowań, które nigdy nie powinny wystąpić. W ramach testów zgodności reguły SELinux neverallow są teraz stosowane na wszystkich urządzeniach.

Poniższe wskazówki mają pomóc producentom uniknąć błędów związanych z regułami neverallow podczas dostosowywania. Numery reguł użyte w tym dokumencie odpowiadają Androidowi 5.1 i mogą ulec zmianie w kolejnych wersjach.

Reguła 48: neverallow { domain -debuggerd -vold -dumpstate -system_server } self:capability sys_ptrace;
Zobacz stronę man dla ptrace. Umożliwia ona ptrace dowolnego procesu, co daje dużą kontrolę nad innymi procesami i powinna dotyczyć tylko określonych komponentów systemu, opisanych w regułach.sys_ptrace Wymóg tej funkcji często wskazuje na obecność czegoś, co nie jest przeznaczone do wersji przeznaczonych dla użytkowników, lub funkcji, które nie są potrzebne. Usuń niepotrzebny komponent.

Reguła 76: neverallow { domain -appdomain -dumpstate -shell -system_server -zygote } { file_type -system_file -exec_type }:file execute;
Ta reguła ma na celu zapobieganie wykonywaniu dowolnego kodu w systemie. W szczególności zapewnia, że uruchomiony zostanie tylko kod na /system, co gwarantuje bezpieczeństwo dzięki mechanizmom takim jak weryfikacja podczas uruchamiania. Często najlepszym rozwiązaniem w przypadku problemu z tą regułą neverallow jest przeniesienie kodu, który ją narusza, na partycję /system.

dostosowywać SEPolicy w Androidzie 8.0 i nowszych,

W tej sekcji znajdziesz wskazówki dotyczące zasad SELinux dostawcy w Androidzie 8.0 i nowszych, w tym szczegóły dotyczące projektu SEPolicy w ramach Projektu Android Open Source (AOSP) i rozszerzeń SEPolicy. Więcej informacji o tym, jak zasady SELinux są utrzymywane w zgodzie z podziałem na partycje i wersjami Androida, znajdziesz w sekcji Zgodność.

Zasady rozmieszczenia

W Androidzie 7.0 i starszych producenci urządzeń mogli dodawać zasady do BOARD_SEPOLICY_DIRS, w tym zasady mające uzupełniać zasady AOSP na różnych typach urządzeń. W Androidzie 8.0 i nowszych dodanie zasady do BOARD_SEPOLICY_DIRS umieszcza ją tylko w obrazie dostawcy.

W Androidzie 8.0 i nowszych zasady znajdują się w tych lokalizacjach w AOSP:

  • system/sepolicy/public. Obejmuje zasady wyeksportowane do użycia w zasadach dostawcy. Wszystko trafia do infrastruktury zgodności w Androidzie 8.0. Public policy ma być zachowana w przypadku kolejnych wersji, dlatego możesz uwzględnić w swoich niestandardowych zasadach dowolne elementy /public. W związku z tym typ zasad, które można umieścić w /public, jest bardziej ograniczony. Zastanów się nad wyeksportowanym interfejsem API zasad platformy: wszystko, co ma związek z interfejsem /system/vendor.
  • system/sepolicy/private. Zawiera zasady niezbędne do działania obrazu systemu, ale producent nie powinien znać zasad dotyczących obrazu.
  • system/sepolicy/vendor. Obejmuje zasady dotyczące komponentów, które są umieszczane w katalogu /vendor, ale znajdują się w głównym drzewie platformy (nie w katalogach na urządzenia). Jest to artefakt związany z rozróżnieniem urządzeń i komponentów globalnych w systemie kompilacji. Koncepcyjnie jest to część zasad dotyczących poszczególnych urządzeń opisanych poniżej.
  • device/manufacturer/device-name/sepolicy. Obejmuje zasady dotyczące urządzeń. Obejmuje też dostosowanie urządzenia do zasad, które w Androidzie 8.0 i nowszych odpowiadają zasadom dla komponentów w obrazu dostawcy.

W Androidzie 11 i nowszych partycje system_ext i produktowe mogą też zawierać zasady dotyczące konkretnych partycji. Zasady system_ext i produktowe są też podzielone na publiczne i prywatne, a dostawcy mogą używać publicznych zasad system_ext i produktowych, takich jak zasady systemowe.

  • SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS. Obejmuje zasady wyeksportowane do użycia w zasadach dostawcy. Zainstalowany na partycji system_ext.
  • SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS. Zawiera zasady niezbędne do działania obrazu system_ext, ale nie ma dostępu do zasad obrazu dostawcy. Zainstalowany na partycji system_ext.
  • PRODUCT_PUBLIC_SEPOLICY_DIRS. Obejmuje zasady wyeksportowane do użycia w zasadach dostawcy. Zainstalowany na partycji produktu.
  • PRODUCT_PRIVATE_SEPOLICY_DIRS. Zawiera zasady niezbędne do funkcjonowania obrazu produktu, ale producent nie powinien znać zasad dotyczących obrazu. Zainstalowany na partycji produktu.
Uwaga: gdy używana jest GSI, partycje system_ext i product OEM nie będą montowane. Reguły w pliku sepolicy dostawcy, który używa zasad publicznych system_ext i produkt OEM, stają się nieaktywne, ponieważ brakuje definicji typów dla OEM.
Uwaga: zachowaj szczególną ostrożność podczas używania atrybutu system_ext i publicznych zasad dotyczących produktów. Publiczne zasady działają jak wyeksportowany interfejs API między systemem_ext/product a dostawcą. Partnerzy powinni samodzielnie zarządzać problemami ze zgodnością.

Obsługiwane scenariusze zasad

Na urządzeniach z Androidem 8.0 lub nowszym obraz dostawcy musi działać z obrazem systemu OEM i referencyjnym obrazem systemu AOSP dostarczonym przez Google (i przejść test CTS na tym obrazie referencyjnym). Wymagania te zapewniają wyraźne oddzielenie platformy od kodu dostawcy. Takie urządzenia obsługują te scenariusze:

rozszerzenia tylko z obrazem dostawcy,

Przykład: dodanie nowej usługi do vndservicemanager z obrazu dostawcy, który obsługuje procesy z obrazu dostawcy.

Podobnie jak w przypadku urządzeń z poprzednimi wersjami Androida, dodaj opcje dostosowywania do konkretnego urządzenia w sekcji device/manufacturer/device-name/sepolicy. Nowa zasada regulująca sposób interakcji komponentów dostawcy (tylko) z innymi komponentami dostawcy powinna obejmować typy występujące tylko w device/manufacturer/device-name/sepolicy. Zasady zapisane tutaj umożliwiają działanie kodu dostawcy, nie będą aktualizowane w ramach aktualizacji OTA tylko dla frameworka i są obecne w złożonych zasadach na urządzeniu z obrazu systemu AOSP.

obsługa obrazu dostawcy do pracy z AOSP;

Przykład: dodanie nowego procesu (zarejestrowanego w hwservicemanager z obrazu dostawcy), który implementuje interfejs HAL zdefiniowany w AOSP.

Podobnie jak w przypadku urządzeń z poprzednimi wersjami Androida, w device/manufacturer/device-name/sepolicy możesz dostosować ustawienia dotyczące konkretnego urządzenia. Zasady wyeksportowane w ramach system/sepolicy/public/ są dostępne do użycia i są dostarczane w ramach zasad dostawcy. Typy i atrybuty z zasad publicznych mogą być używane w nowych regułach określających interakcje z nowymi bitami specyficznymi dla danego dostawcy, z zastrzeżeniem podanych ograniczeń neverallow. Podobnie jak w przypadku dostawcy, nowe zasady nie będą aktualizowane w ramach OTA tylko dla frameworka. Będą one obecne w połączonych zasadach na urządzeniu z odwołującym się do AOSP obrazem systemu.

rozszerzenia tylko z obrazem systemowym

Przykład: dodanie nowej usługi (zarejestrowanej w servicemanagerze), do której dostęp mają tylko inne procesy z obrazu systemu.

Dodaj tę zasadę do system/sepolicy/private. Możesz dodawać dodatkowe procesy lub obiekty, aby włączyć funkcje w systemie partnera, o ile te nowe elementy nie muszą wchodzić w interakcje z nowymi komponentami w systemie dostawcy (czyli takie procesy lub obiekty muszą w pełni działać bez zasad z systemu dostawcy). Zasady wyeksportowane przez system/sepolicy/public są dostępne tutaj tak samo jak w przypadku rozszerzeń zawierających tylko obrazy dostawcy. Ta zasada jest częścią obrazu systemu i może zostać zaktualizowana w ramach bezprzewodowej aktualizacji tylko dla frameworka, ale nie będzie obecna w przypadku obrazu systemu AOSP.

rozszerzenia obrazu dostawcy, które obsługują rozszerzone komponenty AOSP;

Przykład: nowy interfejs HAL niebędący interfejsem AOSP, przeznaczony do użycia przez rozszerzonych klientów, którzy występują również w ramach obrazu systemu AOSP (np. rozszerzony system_server).

Zasady interakcji między systemem a dostawcą muszą być uwzględnione w katalogu device/manufacturer/device-name/sepolicydostarczonym w partycji dostawcy. Jest to podobne do opisanego powyżej scenariusza dodania obsługi obrazu dostawcy, aby działał on z obrazem referencyjnym AOSP, z tym że zmodyfikowane komponenty AOSP mogą też wymagać dodatkowych zasad, aby prawidłowo działać z resztą partycji systemu (co jest dopuszczalne, o ile nadal mają etykiety typu publicznego typu AOSP).

Zasady dotyczące interakcji publicznych komponentów AOSP z rozszerzeniami tylko dla obrazu systemu powinny znajdować się w system/sepolicy/private.

rozszerzenia obrazów systemowych, które uzyskują dostęp tylko do interfejsów AOSP;

Przykład: nowy proces systemowy, który nie jest zgodny z AOSP, musi mieć dostęp do HAL, na którym opiera się AOSP.

Jest to podobne do przykładu rozszerzenia z tylko obrazem systemu, z tym wyjątkiem, że nowe komponenty systemu mogą wchodzić w interakcje z interfejsem system/vendor. Zasady dotyczące nowego komponentu systemu muszą być zawarte w system/sepolicy/private, co jest dopuszczalne, o ile odbywa się to za pomocą interfejsu już utworzonego przez AOSP w system/sepolicy/public (czyli typy i atrybuty wymagane do działania). Chociaż zasady można uwzględnić w zasadach dotyczących urządzenia, nie można używać innych typów system/sepolicy/private ani zmieniać (w żaden sposób wpływający na zasady) w ramach aktualizacji tylko dla frameworka. Zasady mogą zostać zmienione w ramach aktualizacji OTA tylko dla frameworka, ale nie będą obecne w przypadku obrazu systemu AOSP (który nie będzie też zawierać nowego komponentu systemu).

rozszerzenia graficzne dostawcy, które wyświetlają nowe komponenty systemu;

Przykład: dodanie nowego HAL-a, który nie jest zgodny z AOSP, do użycia przez proces klienta bez analogu AOSP (wymaga własnej domeny).

Podobnie jak w przykładzie rozszerzeń AOSP zasady dotyczące interakcji między systemem a dostawcą muszą znajdować się w katalogu device/manufacturer/device-name/sepolicydostarczanym w partycji dostawcy (aby zapewnić, że zasady systemu nie mają dostępu do informacji o dostawcy). Możesz dodać nowe typy publiczne, które rozszerzają zasady w system/sepolicy/public. Należy to zrobić tylko w dodatku do istniejących zasad AOSP, czyli nie usuwać zasad publicznych AOSP. Nowe publiczne typy mogą być używane do zasad w system/sepolicy/privatedevice/manufacturer/device-name/sepolicy.

Pamiętaj, że każda dodatkowa funkcja w system/sepolicy/public zwiększa złożoność, ponieważ wiąże się z nową gwarancją zgodności, która musi być śledzona w pliku mapowania i podlega innym ograniczeniom. Do atrybutu system/sepolicy/public można dodawać tylko nowe typy i odpowiednie reguły zezwalające. Atrybuty i inne oświadczenia zasad nie są obsługiwane. Ponadto nowych publicznych typów nie można używać do bezpośredniego oznaczania obiektów w zasadach /vendor.

Nieobsługiwane scenariusze dotyczące zasad

Urządzenia z Androidem 8.0 lub nowszym nie obsługują poniższych scenariuszy i przykładów zasad.

dodatkowe rozszerzenia obrazu systemu, które wymagają uprawnień do nowych komponentów obrazu dostawcy po aktualizacji OTA tylko dla frameworka.

Przykład: nowy proces systemowy niezgodny z AOSP, który wymaga własnej domeny, został dodany w kolejnych wersjach Androida i wymaga dostępu do nowego interfejsu HAL niezgodnego z AOSP.

Podobnie jak w przypadku interakcji nowego systemu (nie AOSP) i komponentów dostawcy, z tym że nowy typ systemu jest wprowadzany w ramach bezprzewodowej aktualizacji OTA dotyczącej tylko frameworka. Chociaż nowy typ można dodać do zasad w system/sepolicy/public, istniejące zasady dostawcy nie uwzględniają nowego typu, ponieważ uwzględniają tylko zasady publiczne systemu Android 8.0. AOSP obsługuje to, udostępniając zasoby dostarczone przez dostawcę za pomocą atrybutu (na przykład atrybutu hal_foo), ale ponieważ rozszerzenia atrybutów partnera nie są obsługiwane w system/sepolicy/public, ta metoda jest niedostępna dla zasad dostawcy. Dostęp musi być udostępniony za pomocą wcześniej utworzonego typu publicznego.

Przykład: zmiana procesu systemowego (AOSP lub niebędącego AOSP) musi zmienić sposób interakcji z nowym komponentem dostawcy, który nie jest zgodny z AOSP.

Zasady dotyczące obrazu systemu muszą być sformułowane bez znajomości konkretnych dostosowań dostawcy. Zasady dotyczące konkretnych interfejsów w AOSP są zatem udostępniane za pomocą atrybutów w system/sepolicy/public, aby dostawca mógł włączyć przyszłe zasady systemowe, które używają tych atrybutów. Rozszerzenia atrybutów w system/sepolicy/public nie są jednak obsługiwane, dlatego wszystkie zasady określające sposób interakcji komponentów systemu z nowymi komponentami dostawcy (które nie są obsługiwane przez atrybuty obecne w AOSP system/sepolicy/public) muszą być zawarte w device/manufacturer/device-name/sepolicy. Oznacza to, że typy systemów nie mogą zmieniać dostępu do typów dostawców w ramach OTA tylko dla frameworka.