Zapoznaj się z tą stroną, aby dowiedzieć się więcej o koncepcjach SELinux.
Wymagana kontrola dostępu
Security Enhanced Linux (SELinux) to system kontroli dostępu (MAC) dla systemu operacyjnego Linux. System MAC różni się od znanego systemu kontroli dostępu w Linuxie (DAC). W systemie DAC istnieje pojęcie własności, w którym właściciel danego zasobu kontroluje powiązane z nim uprawnienia dostępu. Jest to zazwyczaj ogólne i podlega niezamierzonej eskalacji uprawnień. System MAC konsultuje się jednak z centralnym urzędem, aby uzyskać decyzję w przypadku wszystkich prób dostępu.
SELinux został zaimplementowany w ramach modułu zabezpieczeń systemu Linux (LSM), który rozpoznaje różne obiekty jądra i wykonywane na nich działania o charakterze poufnym. W momencie wykonania każdego z tych działań wywoływana jest funkcja haka LSM, która na podstawie informacji przechowywanych w nieprzezroczystym obiekcie zabezpieczeń określa, czy działanie powinno zostać dozwolone. SELinux zapewnia implementację tych punktów wywołania i zarządzanie tymi obiektami zabezpieczeń, które w połączeniu z własnymi zasadami określają decyzje dotyczące dostępu.
Wraz z innymi zabezpieczeniami Androida polityka kontroli dostępu znacznie ogranicza potencjalne szkody związane z naruszeniem bezpieczeństwa urządzeń i kont. Korzystanie z narzędzi takich jak opcjonalne i obowiązkowe kontrolki dostępu w Androidzie zapewnia strukturę, która gwarantuje, że oprogramowanie działa tylko na minimalnym poziomie uprawnień. Pozwala to ograniczyć skutki ataków i zmniejszyć prawdopodobieństwo nadpisania lub nawet przesłania danych przez błędne procesy.
W Androidzie 4.3 i nowszych SELinux zapewnia kontrolę dostępu w ramach (MAC) tradycyjnych środowisk kontroli dostępu dyskrecjonalnego (DAC). Na przykład oprogramowanie musi zwykle działać jako konto root, aby zapisywać dane na urządzeniach z nieprzetworzonymi blokami. W tradycyjnym środowisku Linuksa opartym na DAC, jeśli użytkownik root zostanie skompromitowany, może zapisywać na każdym urządzeniu z nieprzetworzonymi blokami. Można jednak użyć SELinux do oznaczenia tych urządzeń, aby proces z przypisanym przywilejem root mógł zapisywać dane tylko w tych plikach, które są określone w powiązanych zasadach. Dzięki temu proces nie może nadpisać danych i ustawień systemu poza określonym urządzeniem z nieprzetworzonymi blokami.
Więcej przykładów zagrożeń i sposobów ich eliminowania za pomocą SELinux znajdziesz w sekcji Przypadki użycia.
Poziomy egzekwowania
SELinux może być implementowany w różnych trybach:
- Zezwalająca – zasada zabezpieczeń SELinux nie jest wymuszana, tylko rejestrowana.
- Egzekwowanie – zasada zabezpieczeń jest egzekwowana i rejestrowana. Niepowodzenia są wyświetlane jako błędy EPERM.
Ten wybór jest binarny i określa, czy Twoje zasady mają wywołać działanie, czy tylko umożliwić Ci zebranie potencjalnych błędów. Tryb zezwalający jest szczególnie przydatny podczas wdrażania.
Typy, atrybuty i reguły
Android korzysta z elementu SELinux o nazwie Type Enforcement (TE) do wdrażania zasad. Oznacza to, że wszystkie obiekty (np. pliki, procesy lub gniazda) mają powiązany typ. Na przykład domyślny typ aplikacji to untrusted_app
. W przypadku procesu jego typ jest też nazywany domeną. Można dodać adnotację do typu za pomocą jednego lub wielu atrybutów. Atrybuty są przydatne do jednoczesnego odwoływania się do wielu typów.
Obiekty są mapowane na klasy (np. plik, katalog, link symboliczny, gniazdo), a różne rodzaje dostępu do każdej klasy są reprezentowane przez uprawnienia.
Na przykład uprawnienie open
istnieje w klasie file
. Typy i atrybuty są regularnie aktualizowane w ramach zasad SELinux w Androidzie, ale uprawnienia i klasy są definiowane statycznie i rzadko aktualizowane w ramach nowej wersji systemu Linux.
Reguła zasady ma postać:allow source target:class permissions;
gdzie:
- Źródło – typ (lub atrybut) tematu reguły. Kto prosi o dostęp?
- Target (Miejsce docelowe) – typ (lub atrybut) obiektu. Do czego ma być przyznany dostęp?
- Class (Klasa) – rodzaj obiektu (np. plik, gniazdo), do którego uzyskujesz dostęp.
- Uprawnienia – wykonywana operacja (lub zestaw operacji) (np. odczyt lub zapis).
Przykład reguły:
allow untrusted_app app_data_file:file { read write };
Oznacza to, że aplikacje mogą odczytywać i zapisywać pliki oznaczone etykietą app_data_file
. Istnieją też inne typy aplikacji. Na przykład isolated_app
jest używany w przypadku usług aplikacji z isolatedProcess=true
w pliku manifestu. Zamiast powtarzać regułę dla obu typów, Android używa atrybutu appdomain
dla wszystkich typów, które obejmują aplikacje:
# Associate the attribute appdomain with the type untrusted_app. typeattribute untrusted_app appdomain; # Associate the attribute appdomain with the type isolated_app. typeattribute isolated_app appdomain; allow appdomain app_data_file:file { read write };
Gdy zostanie napisana reguła, która określa nazwę atrybutu, nazwa ta jest automatycznie rozszerzana na listę domen lub typów powiązanych z atrybutem. Oto niektóre ważne atrybuty:
domain
– atrybut powiązany ze wszystkimi typami procesów,file_type
– atrybut powiązany ze wszystkimi typami plików.
Makra
W przypadku dostępu do plików istnieje wiele rodzajów uprawnień. Na przykład uprawnienie read
nie wystarcza do otwarcia pliku ani wywołania metody stat
. Aby uprościć definiowanie reguł, Android udostępnia zestaw makr do obsługi najczęstszych przypadków. Aby uwzględnić brakujące uprawnienia, takie jak open
, powyższa reguła może zostać zastąpiona przez:
allow appdomain app_data_file:file rw_file_perms;
Więcej przykładów przydatnych makr znajdziesz w plikach global_macros
i te_macros
. Makr należy używać zawsze, gdy to możliwe, aby zmniejszyć prawdopodobieństwo niepowodzenia z powodu odmowy udzielenia uprawnień.
Po zdefiniowaniu typu należy go powiązać z reprezentowanym przez niego plikiem lub procesem. Więcej informacji o tym, jak to zrobić, znajdziesz w artykule Wdrażanie SELinux. Więcej informacji o regułach znajdziesz w notatniku SELinux.
Kontekst i kategorie zabezpieczeń
Podczas debugowania zasad SELinux lub etykietowania plików (za pomocą file_contexts
lub ls -Z
) możesz natknąć się na kontekst zabezpieczeń (znany też jako etykieta). Przykład:
u:r:untrusted_app:s0:c15,c256,c513,c768
. Kontekst zabezpieczeń ma format:
user:role:type:sensitivity[:categories]
. Zwykle możesz zignorować pola user
, role
i sensitivity
w kontekście (patrz Specyficzność). Informacje o polu type
z poprzedniej sekcji. categories
są częścią obsługi zabezpieczeń wielopoziomowych (MLS) w SELinux. W Androidzie 12 i nowszych kategorie służą do:
- izolować dane aplikacji przed dostępem innej aplikacji,
- izolowanie danych aplikacji od jednego użytkownika fizycznego do drugiego;
Specyficzność
Android nie korzysta ze wszystkich funkcji SELinux. Podczas czytania dokumentacji zewnętrznej pamiętaj o tych kwestiach:
- Większość zasad w AOSP jest definiowana za pomocą języka Kernel Policy Language. W przypadku języka wspólnego pośredniego (CIL) obowiązują pewne wyjątki.
- Użytkownicy SELinux nie są używani. Jedynym zdefiniowanym przez użytkownika jest
u
. W razie potrzeby użytkownicy fizyczni są reprezentowani za pomocą pola kategorii w kontekście zabezpieczeń. - Role SELinux i kontrola dostępu oparta na rolach (RBAC) nie są używane. Zdefiniowano i użyto 2 domyślne role:
r
dla podmiotów iobject_r
dla obiektów. - Poziomy zabezpieczeń SELinux nie są używane. Domyślna czułość
s0
jest zawsze ustawiona. - Parametry logiczne SELinux nie są używane. Gdy zasady są tworzone na urządzenie, ich działanie nie zależy od jego stanu. Ułatwia to kontrolowanie i debugowanie zasad.