Kontrolowanie integralności przepływu

Według danych z 2016 roku około 86% wszystkich luk w zabezpieczeniach Androida stanowiło bezpieczeństwo pamięci. powiązanych. Większość luk w zabezpieczeniach jest wykorzystywana przez osoby przeprowadzające atak zmieniając standardowy i kontrolować przepływ aplikacji i wykonywać dowolne złośliwych działań wszystkie uprawnienia wykorzystywanej aplikacji. Sterowanie przepływem pracy (CFI) to mechanizm zabezpieczający, który blokuje wprowadzanie zmian na pierwotnym wykresie przepływu pracy skompilowanego pliku binarnego, co znacznie utrudnia do przeprowadzania takich ataków.

W Androidzie 8.1 włączyliśmy implementację CFI przez LLVM w stosie multimediów. W w Androidzie 9 udostępniliśmy CFI w większej liczbie komponentów oraz w jądrze. Obecny system CFI: jest domyślnie włączone, ale musisz włączyć CFI jądra.

CFI LLVM wymaga skompilowania za pomocą parametru Optymalizacja czasu linku (LTO). LTO zachowuje reprezentację kodu bitowego LLVM z plików obiektów do czasu czas linku, dzięki któremu kompilator będzie mógł lepiej rozumieć, jakie optymalizacje . Włączenie LTO zmniejsza rozmiar ostatecznego pliku binarnego wydajności, ale wydłuża czas kompilacji. W testach na Androidzie połączenie: LTO i CFI skutkują znikomym nakładem pracy nad rozmiarem i wydajnością kodu. w w obu przypadkach udało się rozwiązać problem.

Więcej szczegółów technicznych dotyczących CFI i innych mechanizmów kontroli Patrz: projekt LLVM dokumentacji.

Przykłady i źródło

Interfejs CFI jest dostarczany przez kompilator i dodaje instrumentację do pliku binarnego czas kompilowania. CFI obsługujemy w łańcuchu narzędzi Clang i w systemie kompilacji Androida. w AOSP.

CFI jest domyślnie włączone dla urządzeń Arm64 dla zestawu komponentów w /platform/build/target/product/cfi-common.mk Można ją też włączyć bezpośrednio w zestawie komponentów multimedialnych, utwórz pliki/plan pliki, takie jak /platform/frameworks/av/media/libmedia/Android.bp i /platform/frameworks/av/cmds/stagefright/Android.mk.

Wdrażanie systemowej listy CFI

Interfejs CFI jest domyślnie włączony, jeśli używasz języka Clang i systemu kompilacji Androida. CFI pomaga chronić użytkowników Androida, więc nie należy go wyłączać.

Zdecydowanie zalecamy włączenie CFI dla dodatkowych komponentów. Idealnymi kandydatami są uprzywilejowany kod natywny lub kod natywny, który przetwarza niezaufanych danych wejściowych użytkownika. Jeśli używasz clangu i systemu Android Build, można włączyć CFI w nowych komponentach, dodając kilka wierszy do plików Makerfiles lub plików planów.

Obsługa CFI w makefiles

Aby włączyć CFI w pliku marki, takim jak /platform/frameworks/av/cmds/stagefright/Android.mk: dodaj:

LOCAL_SANITIZE := cfi
# Optional features
LOCAL_SANITIZE_DIAG := cfi
LOCAL_SANITIZE_BLACKLIST := cfi_blacklist.txt

  • LOCAL_SANITIZE określa CFI jako środek dezynfekcyjny tworzyć.
  • LOCAL_SANITIZE_DIAG włącza tryb diagnostyczny CFI. Tryb diagnostyczny wyświetla dodatkowe informacje na potrzeby debugowania w logcat podczas co jest przydatne podczas tworzenia i testowania kompilacji. Marka pamiętaj jednak o usunięciu trybu diagnostycznego w kompilacjach produkcyjnych.
  • LOCAL_SANITIZE_BLACKLIST umożliwia komponentom selektywne wyłączyć instrumentację CFI dla poszczególnych funkcji lub plików źródłowych. Ty mogą używać czarnej listy w ostateczności, żeby rozwiązać problemy dla użytkowników, które mogłyby istnieć w innym miejscu. Więcej informacji: Wyłączanie CFI.

Obsługa CFI w plikach planów

Aby włączyć CFI w pliku planu, na przykład w /platform/frameworks/av/media/libmedia/Android.bp: dodaj:

   sanitize: {
        cfi: true,
        diag: {
            cfi: true,
        },
        blacklist: "cfi_blacklist.txt",
    },

Rozwiązywanie problemów

Jeśli włączysz CFI w nowych komponentach, możesz napotkać problemy błędy niezgodności typu funkcji i niezgodność typu kodu zestawu .

Błędy niezgodności typu funkcji występują, ponieważ CFI ogranicza wywołania pośrednie tylko do przejdź do funkcji o tym samym typie dynamicznym co typ statyczny używany w . CFI ogranicza wirtualne i niewirtualne wywołania funkcji tylko do przechodzenia do obiektów, które są klasą pochodną statycznego typu obiektu używanego do zadzwoń. Jeśli masz kod, który narusza którekolwiek z tych koncepcjach, instrumentacja dodana przez CFI spowoduje przerwanie. Na przykład parametr zrzut stosu pokazuje SIGABRT, a logcat zawiera wiersz dotyczący przepływu sterowania w przypadku integralności w przypadku wykrycia niezgodności.

Aby rozwiązać ten problem, upewnij się, że wywoływana funkcja ma ten sam typ statycznie zadeklarowanych. Oto 2 przykładowe listy zmian:

Inny możliwy problem polega na próbie włączenia CFI w kodzie, który zawiera elementy pośrednie i wezwania do montażu. Ponieważ kod zestawu nie jest wpisany, otrzymujemy typ niezgodność danych.

Aby rozwiązać ten problem, utwórz natywne opakowania kodu dla każdego wywołania zestawu i przypisz do otoczy ten sam podpis funkcji co identyfikator wywołujący. Kod może następnie bezpośrednio wywoływać kod zestawu. Ponieważ gałęzie bezpośrednie nie są instrumentowane przez CFI (nie można ich wskazać ponownie w czasie działania, więc nie stwarzają ryzyka dla bezpieczeństwa) to rozwiąże problem.

Jeśli jest zbyt wiele funkcji montażu i nie da się naprawić wszystkich, możesz a także umieścić na czarnej liście wszystkie funkcje, które zawierają pośrednie wywołania zestawu. To jest nie jest zalecane, ponieważ powoduje wyłączenie kontroli CFI dla tych funkcji, co powoduje otwarcie na powierzchni ataku.

Wyłączam CFI

Nie zaobserwowaliśmy żadnych wzrostów wydajności, więc nie ma potrzeby CFI. Jeśli jednak ma to wpływ na użytkowników, możesz selektywnie wyłączyć CFI. dla poszczególnych funkcji lub plików źródłowych przez udostępnienie pliku czarnej listy narzędzia sanitizer podczas kompilowania danych. Czarna lista zawiera instrukcje dla kompilatora, aby wyłączył CFI w określonych lokalizacjach.

System kompilacji Androida zapewnia obsługę czarnych list dla poszczególnych komponentów (pozwala to na wybrać pliki źródłowe lub poszczególne funkcje, które nie będą otrzymywać CFI instrumentacji) w przypadku twórców i piosenek. Więcej informacji na temat formatu pliku czarnej listy, patrz nadrzędne Kliknij dokumenty.

Weryfikacja

Obecnie nie prowadzimy testów CTS dotyczących CFI. Upewnij się, że Testy CFI zaliczają się zarówno przy włączonym, jak i bez niego CFI, co pozwala sprawdzić, czy CFI nie ma wpływu urządzenia.