Weryfikacja podczas uruchamiania

Weryfikowany rozruch wymaga weryfikacji kryptograficznej całego kodu wykonywalnego i danych, które są częścią wersji Androida uruchamianej przed użyciem. Obejmuje to jądro (wczytane z partycji boot), drzewo urządzenia (wczytane z partycji dtbo), partycję system, partycję vendor itd.

Małe partycje, takie jak boot i dtbo, które są odczytywane tylko raz, są zwykle weryfikowane przez załadowanie całego zawartości do pamięci i obliczenie jej wartości skrótu. Następnie obliczona wartość funkcji haszowania jest porównywana z oczekiwaną wartością funkcji haszowania. Jeśli wartości się nie zgadzają, Android nie wczyta pliku. Więcej informacji znajdziesz w artykule Proces uruchamiania.

Większe partycje, które nie mieszczą się w pamięci (np. systemy plików), mogą używać drzewa haszowania, w którym weryfikacja jest ciągłym procesem, który odbywa się podczas wczytywania danych do pamięci. W tym przypadku skrót główny drzewa skrótów jest obliczany w czasie wykonywania i porównywany z oczekiwaną wartością skrótu głównego. Android zawiera sterownik dm-verity, który weryfikuje większe partycje. Jeśli w jakimś momencie obliczony hash root nie będzie zgodny z oczekiwaną wartością hasha roota, dane nie zostaną użyte, a Android przejdzie w stan błędu. Więcej informacji znajdziesz w artykule Uszkodzenie pliku dm-verity.

Oczekiwane wartości hasz są zwykle przechowywane na końcu lub na początku każdej zweryfikowanej partycji, w dedykowanej partycji lub w obu tych miejscach. Co ważne, te wartości skrótu są podpisane (bezpośrednio lub pośrednio) przez zaufanego głównego urzędu certyfikacji. Na przykład implementacja AVB obsługuje oba podejścia. Więcej informacji znajdziesz w artykule Weryfikacja podczas uruchamiania na Androidzie.

Ochrona przed przywróceniem

Nawet w przypadku całkowicie bezpiecznego procesu aktualizacji możliwe jest, że nietrwały exploit jądra Androida ręcznie zainstaluje starszą, bardziej podatną na ataki wersję Androida, uruchomi ją ponownie, a następnie użyje tej wersji Androida do zainstalowania trwałego exploita. W ten sposób atakujący staje się właścicielem urządzenia i może zrobić z nim wszystko, w tym wyłączyć aktualizacje.

Ochrona przed tą klasą ataków nosi nazwę Rollback Protection (ochrona przed cofaniem). Ochrona przed cofnięciem jest zwykle realizowana przez wykorzystanie pamięci z możliwością wykrycia manipulacji, aby zapisać najnowszą wersję Androida i odmówić uruchomienia Androida, jeśli jest ona starsza niż zapisana wersja. Wersje są zwykle śledzone na podstawie partycji.

Więcej informacji o tym, jak AVB obsługuje zabezpieczenia przed cofnięciem zmian, znajdziesz w pliku README.

Obsługa błędów weryfikacji

Weryfikacja może się nie udać podczas uruchamiania (np. gdy obliczony hasz na partycji boot nie pasuje do oczekiwanego hasza) lub podczas działania (np. gdy dm-verity napotka błąd weryfikacji na partycji system). Jeśli weryfikacja nie powiedzie się podczas uruchamiania, urządzenie nie uruchomi się, a użytkownik będzie musiał wykonać czynności mające na celu przywrócenie urządzenia.

Jeśli weryfikacja nie powiedzie się w czasie działania, proces będzie nieco bardziej skomplikowany. Jeśli urządzenie korzysta z dm-verity, powinno być skonfigurowane w trybie restart. W trybie restart, jeśli wystąpi błąd weryfikacji, urządzenie zostanie natychmiast ponownie uruchomione z określoną flagą wskazującą przyczynę. Bootloader powinien zauważyć ten flagę i przełączyć dm-verity na tryb błędu we/wy (eio) i pozostać w tym trybie do momentu zainstalowania nowej aktualizacji.

Podczas uruchamiania w trybie eio na urządzeniu wyświetla się ekran z błędem informujący użytkownika o wykryciu uszkodzenia i możliwym nieprawidłowym działaniu urządzenia. Ten ekran będzie widoczny, dopóki użytkownik go nie zamknie. W trybie eio sterownik dm-verity nie uruchamia ponownie urządzenia, jeśli wystąpi błąd weryfikacji. Zamiast tego zwracany jest błąd EIO, a aplikacja musi obsłużyć ten błąd.

Chodzi o to, aby uruchomić narzędzie do aktualizacji systemu (aby można było zainstalować nowy system operacyjny bez błędów) lub aby użytkownik mógł przenieść jak najwięcej danych z urządzenia. Po zainstalowaniu nowego systemu operacyjnego program ładujący wykryje nowo zainstalowany system i powróci do trybu restart.