HWAdressSanitizer

O AddressSanitizer assistido por hardware (HWASan) é uma ferramenta de detecção de erros de memória semelhante ao AddressSanitizer . O HWASan usa muito menos RAM em comparação com o ASan, o que o torna adequado para a higienização de todo o sistema. O HWASan está disponível apenas no Android 10 e superior e apenas no hardware AArch64.

Embora útil principalmente para código C/C++, o HWASan também pode ajudar a depurar código Java que causa travamentos em C/C++ usado para implementar interfaces Java. É útil porque detecta erros de memória quando eles acontecem, apontando você diretamente para o código responsável.

Você pode fazer o flash de imagens HWASan pré-construídas para dispositivos Pixel suportados em ci.android.com ( instruções detalhadas de configuração ).

Comparado ao ASan clássico, o HWASan tem:

  • Sobrecarga de CPU semelhante (~2x)
  • Sobrecarga de tamanho de código semelhante (40 – 50%)
  • Sobrecarga de RAM muito menor (10% - 35%)

O HWASan detecta o mesmo conjunto de bugs que o ASan:

  • Estouro/subfluxo de buffer de pilha e heap
  • Uso de pilha depois de gratuito
  • Uso de pilha fora do escopo
  • Duplo livre/livre livre

Além disso, o HWASan detecta o uso da pilha após o retorno.

Detalhes e limitações da implementação

O HWASan é baseado na abordagem de marcação de memória , onde um pequeno valor de tag aleatório é associado a ponteiros e a intervalos de endereços de memória. Para que um acesso à memória seja válido, o ponteiro e as tags de memória devem corresponder. O HWASan conta com o recurso ARMv8 top byte ignore (TBI), também chamado de marcação de endereço virtual , para armazenar a marca de ponteiro nos bits mais altos do endereço.

Você pode ler mais sobre o design do HWASan no site de documentação do Clang.

Por design, o HWASan não possui redzones de tamanho limitado do ASan para detectar estouros ou a quarentena de capacidade limitada do ASan para detectar o uso após a liberação. Por esse motivo, o HWASan pode detectar um bug, não importa o tamanho do estouro ou há quanto tempo a memória foi desalocada. Isso dá ao HWASan uma grande vantagem sobre o ASan.

No entanto, HWASan tem um número limitado de valores de tags possíveis (256), o que significa que há uma probabilidade de 0,4% de perder algum bug durante uma execução do programa.

Requisitos

O HWASan requer que o kernel do Linux aceite ponteiros marcados em argumentos de chamada do sistema. O suporte para isso foi implementado nos seguintes conjuntos de patches upstream:

Esses patches estão disponíveis como backports no kernel Android comum em ramificações android-4.14 e superiores, mas não em ramificações específicas do Android 10, como android-4.14-q .

O suporte de espaço de usuário para HWASan está disponível a partir do Android 11 .

Se você estiver compilando com uma cadeia de ferramentas personalizada, certifique-se de que ela inclua tudo até LLVM commit c336557f .

Usando HWASan

Use os seguintes comandos para construir toda a plataforma usando HWASan:

lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j

Por conveniência, você pode adicionar a configuração SANITIZE_TARGET a uma definição de produto, semelhante a aosp_coral_hwasan .

Ao contrário do ASan, com o HWASan não há necessidade de construir duas vezes. As compilações incrementais simplesmente funcionam, não há instruções especiais de flash ou necessidade de limpeza, executáveis ​​estáticos são suportados e não há problema em pular a sanitização de qualquer biblioteca que não seja libc . Também não há exigência de que, se uma biblioteca for higienizada, qualquer executável vinculado a ela também deva ser higienizado.

Para pular a sanitização de um módulo, use LOCAL_NOSANITIZE := hwaddress ou sanitize: { hwaddress: false } .

Módulos individuais podem ser higienizados com HWASan, com a ressalva de que libc também é HWASan-ified. Isso pode ser feito adicionando sanitize: { hwaddress: true } à respectiva definição do módulo Android.bp . Toda a plataforma Android é construída com HWASan ao usar uma compilação com _hwasan _hwasan (incluindo libc ) e, como tal, a limpeza manual da libc não é necessária para compilações HWASan.

Melhores rastreamentos de pilha

O HWASan usa um desbobinador rápido baseado em ponteiro de quadro para registrar um rastreamento de pilha para cada evento de alocação e desalocação de memória no programa. O Android habilita ponteiros de quadro no código AArch64 por padrão, então isso funciona muito bem na prática. Se você precisar desfazer o código gerenciado, defina HWASAN_OPTIONS=fast_unwind_on_malloc=0 no ambiente do processo. Observe que os rastreamentos de pilha de acesso à memória incorretos usam o desenrolador "lento" por padrão; essa configuração afeta apenas os rastreamentos de alocação e desalocação. Esta opção pode exigir muito da CPU, dependendo da carga.

Simbolização

Consulte Simbolização na documentação do ASan.

HWASan em aplicativos

Semelhante ao AddressSanitizer, o HWASan não pode ver o código Java, mas pode detectar bugs nas bibliotecas JNI. Ao contrário do ASan, a execução de aplicativos HWASan em um dispositivo não HWASan não é compatível.

Em um dispositivo HWASan, os aplicativos podem ser verificados com HWASan construindo seu código com SANITIZE_TARGET:=hwaddress em Make ou -fsanitize=hwaddress em sinalizadores do compilador. Consulte a documentação do desenvolvedor do aplicativo para obter mais detalhes.