Dostosowywanie SELinux

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

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ć:

  1. Użyj najnowszego jądra Androida .
  2. Przyjmij zasadę najmniejszych przywilejów .
  3. Adresuj tylko własne dodatki do Androida. Domyślne zasady działają automatycznie z bazą kodu Android Open Source Project .
  4. Podziel komponenty oprogramowania na moduły, które wykonują pojedyncze zadania.
  5. Twórz polityki 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 zezwalającej w pliku .te domeny.
  8. Analizuj wyniki i udoskonalaj definicje swojej domeny.
  9. 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.
Uwaga: gdy używany jest GSI, partycje system_ext i produktu OEM nie zostaną zamontowane. Reguły w zasadach dostawcy, które używają zasad system_ext i publicznych zasad produktu OEM, stają się NOP, ponieważ brakuje definicji typów specyficznych dla OEM.
Uwaga: Zachowaj szczególną ostrożność podczas korzystania z zasad system_ext i publicznych zasad produktu. Polityki publiczne działają jako eksportowane API między systemem_ext/produktem a dostawcą. Partnerzy powinni sami zarządzać problemami ze zgodnością.

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.