Integralność przepływu sterowania (CFI) to mechanizm bezpieczeństwa, który uniemożliwia zmiany w oryginalnym wykresie przepływu sterowania skompilowanego pliku binarnego, co znacznie utrudnia przeprowadzenie takich ataków.
W systemie Android 9 umożliwiliśmy LLVM implementację CFI w większej liczbie komponentów, a także w jądrze. System CFI jest domyślnie włączony, ale należy włączyć CFI jądra.
CFI LLVM wymaga kompilacji z optymalizacją czasu łącza (LTO) . LTO zachowuje reprezentację plików obiektowych w kodzie bitowym LLVM aż do czasu połączenia, co pozwala kompilatorowi lepiej przemyśleć, jakie optymalizacje można przeprowadzić. Włączenie LTO zmniejsza rozmiar końcowego pliku binarnego i poprawia wydajność, ale wydłuża czas kompilacji. Podczas testowania na Androidzie połączenie LTO i CFI powoduje znikomy narzut związany z rozmiarem kodu i wydajnością; w kilku przypadkach obie uległy poprawie.
Więcej szczegółów technicznych na temat CFI i sposobu obsługi innych kontroli wyprzedzających można znaleźć w dokumentacji projektowej LLVM .
Realizacja
Poprawki kCFI są dostępne we wszystkich obsługiwanych wersjach jądra Androida. Opcja CONFIG_CFI_CLANG
włącza kCFI i jest domyślnie ustawiona w GKI.
Rozwiązywanie problemów
Po włączeniu należy naprawić wszelkie błędy niezgodności typów, które mogą występować w sterownikach. Pośrednie wywołanie funkcji poprzez niezgodny wskaźnik funkcji powoduje błąd CFI. Kiedy zostanie wykryta awaria CFI, jądro wypisuje ostrzeżenie, które zawiera zarówno wywołaną funkcję, jak i ślad stosu, który doprowadził do awarii. Popraw to, upewniając się, że wskaźniki funkcji zawsze mają ten sam typ, co wywoływana funkcja.
Aby pomóc w debugowaniu błędów CFI, włącz CONFIG_CFI_PERMISSIVE
, który wypisuje ostrzeżenie zamiast powodować panikę jądra. Trybu zezwalającego nie można używać w środowisku produkcyjnym.
Walidacja
Obecnie nie ma testu CTS specjalnie dla CFI. Zamiast tego upewnij się, że testy CTS przeszły pomyślnie z włączoną funkcją CFI lub bez niej, aby sprawdzić, czy CFI nie ma wpływu na urządzenie.