O inicialização verificada exige a verificação criptográfica de todos os dados e códigos 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 boot
), a árvore de dispositivos (carregada
da partição dtbo
), a partição system
,
a partição vendor
e assim por diante.
Pequenas partições, como boot
e dtbo
, que são lidas
apenas uma vez, geralmente são verificadas carregando todo o conteúdo na memória e
calculando o hash. Esse valor de hash calculado é comparado ao
valor de hash esperado. Se o valor não corresponder, o Android não será carregado.
Para 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 hashes em que 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 hashes é calculado durante a 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 raiz calculado não corresponder ao valor de hash raiz esperado, os dados não serão usados e o Android entrará em um estado de erro. Para mais detalhes, consulte Corrupção dm-verity.
Os hashes esperados geralmente são armazenados no início ou no fim de cada partição verificada, em uma partição dedicada ou em ambos. É importante ressaltar que esses hashes são assinados (diretamente ou indiretamente) pela raiz de confiança. Por exemplo, a implementação da AVB oferece suporte a ambas as abordagens. Consulte Inicialização verificada do Android para mais detalhes.
Proteção de reversão
Mesmo com um processo de atualização totalmente seguro, é possível que uma exploração de kernel do Android não persistente instale manualmente uma versão mais antiga e mais 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 tem o dispositivo permanentemente e pode fazer qualquer coisa, incluindo desativar atualizações.
A proteção contra essa classe de ataques é chamada de proteção de reversão. A proteção de reversão normalmente é implementada usando armazenamento inviolável para registrar a versão mais recente do Android e recusar a inicialização do Android se ele for anterior à versão registrada. As versões geralmente são rastreadas por partição.
Para mais detalhes sobre como o AVB processa as proteções de reversão, consulte o README (link em inglês) do AVB.
Processar erros de verificação
A verificação pode falhar no momento da inicialização (por exemplo, se o hash calculado na
partição boot
não corresponder ao hash esperado) ou no momento da execução
(por exemplo, se o dm-verity encontrar um erro de verificação na
partição system
). Se a verificação falhar durante a inicialização, o dispositivo
não vai conseguir inicializar, e o usuário final precisará seguir algumas etapas para recuperar o dispositivo.
Se a verificação falhar no momento da execução, o fluxo será um pouco mais complicado. Se o
dispositivo usar dm-verity, ele precisará ser configurado no modo restart
. No
modo restart
, se um erro de verificação for encontrado, o dispositivo será
reiniciado imediatamente com uma flag específica definida para indicar o motivo. O carregador
de inicialização precisa notar essa flag e mudar o 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 que o dispositivo pode não
funcionar corretamente. A tela aparece até que o usuário a dispense. No
modo eio
, o driver dm-verity não reinicia o dispositivo se um
erro de verificação for encontrado. Em vez disso, um erro EIO é retornado, e o
app precisa lidar com o erro.
A intenção é que o atualizador do sistema seja executado (para que um novo SO sem
erros de corrupção possa ser instalado) ou que o usuário consiga transferir o máximo possível
de dados do dispositivo. Depois que o novo SO é instalado, o carregador de inicialização
percebe o SO recém-instalado e volta para o modo restart
.