Verificando a inicialização

A inicialização verificada requer a verificação criptográfica de todos os códigos e dados executáveis ​​que fazem parte da versão do Android que está sendo inicializada antes de ser usada. Isso inclui o kernel (carregado da partição de boot ), a árvore de dispositivos (carregada da partição dtbo ), a partição do system , a partição do vendor e assim por diante.

Pequenas partições, como boot e dtbo , que são lidas apenas uma vez são normalmente verificadas carregando todo o conteúdo na memória e calculando seu hash. Esse valor de hash calculado é então comparado ao valor de hash esperado . Se o valor não corresponder, o Android não será carregado. Para obter mais detalhes, consulte Fluxo de inicialização .

Partições maiores que não cabem na memória (como sistemas de arquivos) podem usar uma árvore de hash onde a verificação é um processo contínuo que ocorre à medida que os dados são carregados na memória. Nesse caso, o hash raiz da árvore de hash é calculado durante o tempo de execução e é verificado em relação ao valor de hash raiz esperado . O Android inclui o driver dm-verity para verificar partições maiores. Se em algum momento o hash de raiz calculado não corresponder ao valor de hash de raiz esperado , os dados não serão usados ​​e o Android entrará em um estado de erro. Para obter mais detalhes, consulte corrupção de dm-verity .

Os hashes esperados são normalmente armazenados no final ou no início de cada partição verificada, em uma partição dedicada ou em ambos. Fundamentalmente, esses hashes são assinados (direta ou indiretamente) pela raiz de confiança. Como exemplo, a implementação do AVB oferece suporte a ambas as abordagens, consulte Inicialização verificada do Android para obter detalhes.

Proteção contra reversão

Mesmo com um processo de atualização completamente seguro, é possível que uma exploração não persistente do kernel do Android instale manualmente uma versão mais antiga e vulnerável do Android, reinicie na versão vulnerável e use essa versão do Android para instalar uma exploração persistente. A partir daí, o invasor possui o dispositivo permanentemente e pode fazer qualquer coisa, incluindo desabilitar atualizações.

A proteção contra essa classe de ataques é chamada de proteção contra reversão . A proteção contra reversão normalmente é implementada usando armazenamento inviolável para registrar a versão mais recente do Android e recusando-se a inicializar o Android se for inferior à versão gravada. As versões geralmente são rastreadas por partição.

Para obter mais detalhes sobre como o AVB lida com as proteções de reversão, consulte o AVB README .

Como lidar com erros de verificação

A verificação pode falhar no momento da inicialização (por exemplo, se o hash calculado na partição de boot não corresponder ao hash esperado) ou no tempo de execução (por exemplo, se o dm-verity encontrar um erro de verificação na partição do system ). Se a verificação falhar no momento da inicialização, o dispositivo não pode inicializar e o usuário final precisa seguir as etapas para recuperar o dispositivo.

Se a verificação falhar em tempo de execução, o fluxo é um pouco mais complicado. Se o dispositivo usa dm-verity, ele deve ser configurado no modo de restart . No modo de restart , se um erro de verificação for encontrado, o dispositivo será reiniciado imediatamente com um sinalizador específico definido para indicar o motivo. O carregador de inicialização deve observar esse sinalizador e alternar dm-verity para usar o modo de erro de E/S ( eio ) e permanecer nesse modo até que uma nova atualização seja instalada.

Ao inicializar no modo eio , o dispositivo mostra uma tela de erro informando ao usuário que a corrupção foi detectada e o dispositivo pode não funcionar corretamente. A tela é exibida até que o usuário a descarte. No modo eio , o driver dm-verity não reiniciará o dispositivo se um erro de verificação for encontrado; em vez disso, um erro EIO é retornado e o aplicativo precisa lidar com o erro.

A intenção é que o atualizador do sistema seja executado (para que um novo sistema operacional sem erros de corrupção possa ser instalado) ou o usuário possa obter o máximo de dados possível do dispositivo. Depois que o novo sistema operacional for instalado, o carregador de inicialização percebe o sistema operacional recém-instalado e volta ao modo de restart .