Dostosuj SELinux

Po zintegrowaniu podstawowej funkcji SELinux i dokładnej analizie wyników możesz dodać własne ustawienia zasad, aby uwzględnić swoje dostosowywanie 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, że zniszczy implementację SELinux na Androidzie i aplikacje, które nim zarządzają. Dotyczy to aplikacji innych firm, które prawdopodobnie będą wymagać ulepszenia, aby były zgodne i działały. 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 wstępnie zdefiniowanych domen
  • Przypisywanie domeny do dowolnego procesu utworzonego jako usługa init
  • Zapoznaj się z makrami, zanim utworzysz zasady
  • Przesyłanie zmian zasad podstawowych do AOSP

Pamiętaj, aby nie:

  • Utwórz niezgodną zasadę
  • Zezwalanie na dostosowywanie zasad dla użytkowników
  • Zezwalanie na dostosowywanie zasad MDM
  • Przestraszanie użytkowników naruszeniami 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 dostosowujesz ustawienia SELinux, zachowaj ostrożność, aby nie uszkodzić dotychczasowych aplikacji. Aby rozpocząć:

  1. Użyj najnowszego 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. oddzielanie komponentów oprogramowania do modułów, 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. Początkowo ustaw nowe domeny jako mniej rygorystyczne. 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 dalsze odmowy.

Po zintegrowaniu zmiany zasad 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 ustawić zbyt szerokie i zbyt zgodne ustawienia niż zbyt restrykcyjne i niezgodne, co powoduje 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 łatkę. 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 od zasad zabezpieczeń bazy danych (domain). Z poprzednich przykładów instrukcji wynika, że DHCP może odczytywać i zapisywać dane w pliku /dev/null.

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

W wierszu init_daemon_domain(dhcp) zasada wskazuje, że protokół DHCP jest wyodrębniony z elementu init i może się z nim komunikować.

W wierszu net_domain(dhcp) zasada pozwala DHCP na korzystanie z typowych funkcji sieciowych z domeny net, takich jak odczytywanie i zapisywanie pakietów TCP, komunikowanie się przez gniazda i wykonywanie żądań DNS.

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

Ostatni blok przykładu rozpoczynający się od allow dhcp netd:fd use; przedstawia, jak aplikacje mogą wchodzić ze sobą w interakcje. 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
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

reguły nigdy nie zezwalaj

Reguły SELinux neverallow zabraniają zachowań, które nigdy nie powinny mieć miejsca. Po przeprowadzeniu testów zgodności reguły SELinux neverallow są teraz egzekwowane na różnych 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 adresu ptrace. Umożliwia ona ptrace dowolnego procesu, co daje dużą kontrolę nad innymi procesami i powinna dotyczyć tylko określonych komponentów systemu wymienionych 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.

Dostosowywanie SEPolicy w Androidzie 8.0 i nowszych

Ta sekcja zawiera 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 zachowywaniu zgodności zasad SELinux na różnych partycjach i w różnych wersjach Androida znajdziesz w sekcji Zgodność.

Zasady dotyczące 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 polityka znajduje 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. Rozumiem, że chodzi o wyeksportowany interfejs API zasad platformy: tutaj należy wszystkie informacje dotyczące interfejsu między /system a /vendor.
  • system/zasad/prywatnych. 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 znajdują się w katalogu /vendor, ale istnieją w głównym drzewie platformy (nie w katalogach dla poszczególnych urządzeń). 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ż dostosowania 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 systemowe i partycje produktu mogą też zawierać zasady dla poszczególnych partycji. Zasady system_ext i zasady usługi są też podzielone na publiczne i prywatne, a dostawcy mogą korzystać z zasad publicznych systemu system_ext i produktów, np. zasad systemowych.

  • SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS. Zawiera zasady wyeksportowane do użycia w zasadach dostawcy. Zainstalowano na partycji system_ext.
  • SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS. Zawiera zasady niezbędne do działania obrazu system_ext, ale o których zasadach dotyczących obrazu dostawcy nie można mieć wiedzy. Zainstalowano na partycji system_ext.
  • PRODUCT_PUBLIC_SEPOLICY_DIRS. Zawiera 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: w przypadku korzystania z GSI partycje system_ext i partycje produktu nie będą podłączone. Reguły w ustawieniach dostawcy, które korzystają z zasad systemowych (system_ext) i zasad publicznych produktu, zmienią się w „NOP”, ponieważ brakuje definicji typu konkretnego OEM.
Uwaga: zachowaj szczególną ostrożność podczas używania atrybutu system_ext i publicznych zasad dotyczących produktów. Publiczne zasady działają jako wyeksportowany interfejs API między systemem_ext/usługą 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 do obiektu vndservicemanager nowej usługi z obrazu dostawcy, który obsługuje procesy z obrazu dostawcy.

Podobnie jak w przypadku urządzeń z poprzednimi wersjami Androida, dodaj personalizację na potrzeby konkretnego urządzenia w pliku 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. Zapisana tutaj zasada umożliwia działanie kodu dostawcy, nie będzie aktualizowany w ramach OTA tylko dla platformy i znajduje się w połączonym zasadzie 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 interfejs HAL zdefiniowany przez 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 dotyczącymi dostawców, 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 z samym 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 wymagają interakcji 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 aktualizacji OTA 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 dodawania obsługi obrazu dostawcy do pracy z obrazu AOSP referencyjnego, 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 pliku system/sepolicy/private.

rozszerzenia obrazów systemowych, które mają 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 są tam 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 dodawać nowe typy publiczne, które rozszerzają tę zasadę w system/sepolicy/public. Należy to robić tylko w uzupełnieniu dotychczasowej zasady AOSP, tzn. nie usuwaj zasady publicznej AOSP. Nowe typy publicznych danych można następnie używać 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. W system/sepolicy/public można dodawać tylko nowe typy i odpowiadające im reguły zezwalające. Atrybuty i inne instrukcje dotyczące zasad nie są obsługiwane. Ponadto nowych typów publicznych nie można używać do bezpośredniego oznaczania obiektów w zasadach /vendor.

Nieobsługiwane scenariusze związane z zasadami

Urządzenia z Androidem 8.0 lub nowszym nie obsługują następujących scenariuszy i przykładów zasad.

Dodatkowe rozszerzenia obrazu systemu, które wymagają uprawnień do nowych komponentów obrazu dostawcy po aktualizacji OTA dostępnej tylko na platformie

Przykład: nowy proces systemowy, który nie jest zgodny z AOSP i wymaga własnego domeny, został dodany w kolejne wersji Androida i wymaga dostępu do nowego interfejsu HAL, który nie jest zgodny 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ż można dodać nowy typ do zasady w system/sepolicy/public, istniejąca zasada dostawcy nie ma informacji o nowym typie, ponieważ śledzi jedynie zasadę publiczną w systemie Android 8.0. AOSP udostępnia zasoby dostarczone przez dostawcę za pomocą atrybutu (np. atrybutu hal_foo). Ponieważ rozszerzenia atrybutów partnera nie są obsługiwane w system/sepolicy/public, ta metoda jest niedostępna dla zasady dostawcy. Dostęp musi być zapewniany przez istniejący wcześniej typ publiczny.

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ć napisane 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ą obsługiwane, dlatego wszystkie zasady określające sposób interakcji komponentów systemu z nowymi komponentami dostawców (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.