Wdrażanie SELinux

SELinux ma ustawione domyślne odmowa dostępu, co oznacza, że każdy dostęp który ma zaczep w jądrze, musi być wyraźnie dozwolony przez zasadę. Ten oznacza, że plik zasad zawiera dużą ilość informacji na temat reguły, typy, zajęcia, uprawnienia i nie tylko. Pełne omówienie SELinux wykracza poza zakres tego dokumentu, ale umiejętność pisania reguły zasad mają teraz zasadnicze znaczenie przy tworzeniu nowych urządzeń z Androidem. Jest jest już mnóstwo informacji na temat SELinux. Patrz sekcja Pomoc techniczna dokumentacji z sugerowanymi materiałami.

Pliki kluczy

Aby włączyć SELinux, zintegruj najnowsze jądra Androida, a potem dołącz pliki znalezione system/zasady zasad katalogu. Po skompilowaniu te pliki stanowią zabezpieczenia jądra SELinux i obejmują starsze wersje systemu operacyjnego Android.

Ogólnie nie należy modyfikować plików system/sepolicy bezpośrednio. Zamiast tego możesz dodawać lub edytować własne pliki zasad dla konkretnych urządzeń w /device/manufacturer/device-name/sepolicy katalogu. W Androidzie 8.0 i nowszych zmiany wprowadzane w tych plikach powinny mają wpływ tylko na zasady w katalogu dostawcy. Więcej informacji na temat rozdzielania publiczna sepolicy w Androidzie 8.0 i nowszych, patrz Dostosowywanie SEPolicy w Androidzie 8.0 lub nowszy. Niezależnie od wersji Androida nadal modyfikujesz te pliki:

Pliki zasad

Pliki z końcówką *.te to pliki źródłowe zasad SELinux, definiowania domen i ich etykiet. Może być konieczne utworzenie nowych plików zasad w /device/manufacturer/device-name/sepolicy, ale staraj się aktualizować istniejące pliki, gdy tylko jest to możliwe.

Pliki kontekstu

W plikach kontekstowych określa się etykiety obiektów.

  • file_contexts przypisuje etykiety do plików i jest używany przez różne komponentów przestrzeni użytkownika. Podczas tworzenia nowych zasad utwórz lub zaktualizuj ten plik , aby przypisać nowe etykiety do plików. Aby zastosować nową file_contexts, ponownie utworzyć obraz systemu plików lub uruchomić restorecon dla pliku, zmienić etykiety. Po przejściu na nową wersję file_contexts automatycznie stosowane do partycji danych systemu i użytkownika w ramach . Zmiany mogą być też stosowane automatycznie przy uaktualnianiu innych partycje, dodając restorecon_recursive wywołań do init.board.rc po podłączeniu partycji do odczytu i zapisu.
  • genfs_contexts przypisuje etykiety do systemów plików, takich jak proc lub vfat, które nie obsługują rozszerzeń . Ta konfiguracja jest wczytywana jako część zasady jądra, ale zmiany mogą nie zadziałać w przypadku izorów w rdzeniu, wymagając ponownego uruchomienia lub odłącz i ponownie podłącz system plików, aby w pełni zastosować zmianę. Określone etykiety można też przypisywać do określonych punktów montowania, takich jak vfat za pomocą opcji context=mount.
  • property_contexts przypisuje etykiety do właściwości systemu Android do: i kontrolować, jakie procesy mogą je ustawiać. Ta konfiguracja jest odczytywana przez Proces init podczas uruchamiania.
  • service_contexts przypisuje etykiety do usług powiązań na Androidzie do: kontrolować, które procesy mogą dodawać (rejestrować) i znajdować (wyszukiwać) powiązanie odniesienia do usługi. Ta konfiguracja jest odczytywana przez Proces servicemanager podczas uruchamiania.
  • seapp_contexts przypisuje etykiety do procesów aplikacji i /data/data katalogu. Ta konfiguracja jest odczytywana przez zygote proces przy każdym uruchomieniu aplikacji i przez installd podczas uruchamiania.
  • mac_permissions.xml przypisuje do aplikacji tag seinfo na podstawie ich podpisu i opcjonalnie nazwy pakietu. Tag seinfo może być następnie używany jako klucz w seapp_contexts, aby przypisać określoną etykietę do wszystkich aplikacji z ten tag seinfo. Ta konfiguracja jest odczytywana przez system_server podczas uruchamiania.
  • keystore2_key_contexts przypisuje etykiety do przestrzeni nazw magazynu kluczy 2.0. Te przestrzenie nazw są egzekwowane przez demona magazynu kluczy2. Magazyn kluczy zawsze używał podane przestrzenie nazw oparte na identyfikatorach UID/AID. Magazyn kluczy w wersji 2.0 dodatkowo wymusza stosowanie zasad przestrzeni nazw. Szczegółowy opis formatu i konwencji znajdziesz tutaj.

Plik Makefile BoardConfig.mk

Po edytowaniu lub dodaniu plików zasad i kontekstów zaktualizuj /device/manufacturer/device-name/BoardConfig.mk utwórz plik, aby odwoływać się do podkatalogu sepolicy i każdego nowego pliku zasad. Więcej informacji na temat zmiennych BOARD_SEPOLICY znajdziesz tutaj: system/sepolicy/README.

BOARD_SEPOLICY_DIRS += \
        <root>/device/manufacturer/device-name/sepolicy

BOARD_SEPOLICY_UNION += \
        genfs_contexts \
        file_contexts \
        sepolicy.te

Po odbudowie urządzenie zostanie włączone z SELinux. Teraz możesz: dostosować zasady SELinux, aby dostosować systemu operacyjnego Android zgodnie z opisem w dostosowania lub weryfikacji istniejąca konfiguracja, jak opisano w Weryfikacja.

Po wdrożeniu nowych plików zasad i aktualizacji BoardConfig.mk są automatycznie wbudowane w ostateczny plik zasad jądra. Więcej informacji na temat tworzenia zasad Sepolicy na urządzeniu znajdziesz w sekcji Sepolicy tworzenia zasad.

Implementacja

Aby rozpocząć korzystanie z SELinux:

  1. Włącz SELinux w jądrze: CONFIG_SECURITY_SELINUX=y
  2. Zmień parametr kernel_cmdline lub polecenie startconfig tak, aby:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    lub
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    Służy tylko do wstępnego opracowywania zasad na urządzeniu. Po masz początkową zasadę wczytywania, usuń ten parametr, urządzenie wymusza stosowanie, w przeciwnym razie zakończy się niepowodzeniem CTS.
  3. Uruchom system w trybie mniej rygorystycznym i sprawdź, jakie odmowy pojawiają się podczas uruchamiania:
    W systemie Ubuntu 14.04 lub nowszym:
    adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
    
    W systemie Ubuntu 12.04:
    adb pull /sys/fs/selinux/policy
    adb logcat -b all | audit2allow -p policy
    
  4. Oceń wyniki pod kątem ostrzeżeń podobnych do init: Warning! Service name needs a SELinux domain defined; please fix! Zobacz Weryfikacja instrukcji i narzędziami.
  5. Zidentyfikuj urządzenia i inne nowe pliki, które wymagają etykiet.
  6. Użyj istniejących lub nowych etykiet obiektów. Spójrz na *_contexts plików, aby zobaczyć, jak elementy były wcześniej oznaczone etykietami i wykorzystaj wiedzę o znaczeniu etykiety w celu przypisania nowej. Najlepiej, jest to istniejąca etykieta, która będzie zgodna z zasadami, ale czasami będzie potrzebna nowa etykieta, a reguły dostępu do niej będą niezbędną. Dodaj etykiety do odpowiednich plików kontekstowych.
  7. Określ domeny/procesy, które powinny mieć własne domeny zabezpieczeń. Prawdopodobnie będziesz musiał stworzyć zupełnie nową zasadę dla każdego z nich. Wszystkie usługi generowane z init powinny mieć swoje własnych. Opisane poniżej polecenia pomagają wyświetlić te, które nadal są uruchomione (ale WSZYSTKIE) wymagają takiego traktowania):
    adb shell su -c ps -Z | grep init
    
    adb shell su -c dmesg | grep 'avc: '
    
  8. Przejrzyj dokument init.device.rc, aby znaleźć domeny, w których nie mają typu domeny. Udostępnij im domenę wcześniej w programowania, aby uniknąć dodawania reguł do init lub myląc dostęp init z tymi, które są w ich do własnych zasad.
  9. Aby używać aplikacji BOARD_SEPOLICY_*, skonfiguruj BOARD_CONFIG.mk zmiennych. Zobacz README (w języku angielskim) w system/sepolicy, aby dowiedzieć się, jak to skonfigurować.
  10. Sprawdź pliki init.device.rc oraz fstab.device i upewnij się, że każde użycie mount odpowiada prawidłowemu system plików z etykietą lub opcja context= mount określone dane.
  11. Przejrzyj każdą odmowę i utwórz zasadę SELinux, która będzie obsługiwać każdą z nich. Zobacz przykłady w sekcji Dostosowywanie.

Zacznij od zasad podanych w AOSP, a następnie na ich podstawie na własne potrzeby. Więcej informacji o strategii dotyczącej zasad dokładniej przyjrzeć się niektórym z tych kroków, zobacz Zapisywanie zasad SELinux.

Przykłady zastosowań

Oto kilka przykładów luk w zabezpieczeniach, które warto wziąć pod uwagę podczas tworzenia własnych treści i powiązane zasady SELinux:

Dowiązania symboliczne – ponieważ są wyświetlane jako pliki, często są i odczytać je jako pliki, co może prowadzić do ataku. Na przykład dla niektórych takich jak init, zmieniać uprawnienia określonych plików ze względu na nadmierną otwartość.

Osoby przeprowadzające atak mogą zastąpić te pliki dowiązaniami symbolicznymi do kontrolowanego przez nich kodu. co pozwoli atakującym zastąpić dowolne pliki. Jeśli jednak wiesz, aplikacja nigdy nie będzie przemierzać dowiązania symbolicznego, możesz tego zabronić z SELinux.

Pliki systemowe – weź pod uwagę klasę plików systemowych, które powinna być modyfikowana tylko przez serwer systemu. Od netd, Przeglądarki init i vold działają jako użytkownik root i mają dostęp tych plików systemowych. Jeśli więc zabezpieczenia netd zostałyby przejęte, te pliki, a potencjalnie również sam serwer systemu,

SELinux umożliwia zidentyfikowanie tych plików jako plików danych serwera systemowego. Dlatego jedyną domeną, która ma uprawnienia do odczytu i zapisu, jest serwer systemu. Nawet jeśli domena netd zostanie przejęta, nie będzie mogła przełączyć domen na w domenie serwera systemowego i uzyskać dostęp do tych plików systemowych, mimo że są one używane jako użytkownik root.

Dane aplikacji – innym przykładem jest klasa funkcji, które musi działać jako użytkownik root, ale nie powinien mieć dostępu do danych aplikacji. To niesamowite, przydatne, ponieważ mogą być zgłaszane asercje o szerokim zakresie, na przykład określone domeny niepowiązane do danych aplikacji, które nie mogą uzyskiwać dostępu do internetu.

setattr – na potrzeby poleceń takich jak chmod czy chown, możesz zidentyfikować zbiór plików, w których powiązane domena może przeprowadzić setattr. Wszystko, co poza tym, może być zabronione nawet przez poziom główny. Aplikacja może więc być uruchamiana chmod i chown w porównaniu z tymi z etykietami app_data_files, ale nie shell_data_files lub system_data_files.