Consulte Entendendo os relatórios do HWASan para obter informações sobre como ler as falhas do HWASan!
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 sanitizaçã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++, 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 diretamente para o código responsável.
Você pode atualizar imagens HWASan pré-criadas para dispositivos Pixel compatíveis em ci.android.com ( instruções de configuração detalhadas ).
Comparado ao clássico ASan, o HWASan possui:
- 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 do buffer de pilha e heap
- Uso de pilha depois de livre
- Uso de pilha fora do escopo
- Duplo grátis/livre selvagem
Além disso, o HWASan detecta o uso da pilha após o retorno.
HWASan (o mesmo que ASan) é compatível com UBSan , ambos podem ser ativados em um destino ao mesmo tempo.
Detalhes e limitações da implementação
O HWASan é baseado na abordagem de marcação de memória , em que um pequeno valor de marca aleatória é 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 depende do recurso ARMv8 de ignorar o byte superior (TBI), também chamado de marcação de endereço virtual , para armazenar a marca do 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 depois de livre. Por esse motivo, o HWASan pode detectar um bug, independentemente do 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 possíveis valores de tag (256), o que significa que há uma probabilidade de 0,4% de perder algum bug durante uma execução do programa.
Requisitos
Versões recentes (4.14+) do kernel Android comum suportam HWASan pronto para uso. As ramificações específicas do Android 10 não têm suporte para HWASan.
O suporte do espaço do usuário para HWASan está disponível a partir do Android 11 .
Se você estiver trabalhando com um kernel diferente, 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:
- arm64 endereço marcado ABI
- arm64: desmarque os ponteiros do usuário passados para o kernel
- mm: Evite criar aliases de endereços virtuais em brk()/mmap()/mremap()
- arm64: valida endereços marcados em access_ok() chamado de threads do kernel
Se você estiver construindo com uma cadeia de ferramentas customizada, certifique-se de incluir 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 incluir a configuração SANITIZE_TARGET em uma definição de produto, semelhante a aosp_coral_hwasan .
Para usuários familiarizados com AddressSanitizer, muita complexidade de compilação foi eliminada:
- Não há necessidade de executar make duas vezes.
- Compilações incrementais funcionam imediatamente.
- Não há necessidade de atualizar os dados do usuário.
Algumas restrições do AddressSanitizer também desapareceram:
- Executáveis estáticos são suportados.
- Não há problema em ignorar a sanitização de qualquer destino que não seja libc. Ao contrário do ASan, não há nenhum requisito de que, se uma biblioteca for limpa, qualquer executável que vincule a ela também deve ser.
Alternar entre HWASan e imagens regulares no mesmo (ou superior) número de compilação pode ser feito livremente. Não é necessário limpar o dispositivo.
Para ignorar a limpeza de um módulo, use LOCAL_NOSANITIZE := hwaddress
(Android.mk) ou sanitize: { hwaddress: false }
(Android.bp).
Sanitizando alvos individuais
O HWASan pode ser ativado por destino em uma compilação regular (não sanitizada), desde que libc.so
também seja sanitizado. Adicione hwaddress: true
ao bloco de limpeza em "libc_defaults"
em bionic/libc/Android.bp. Em seguida, faça o mesmo no alvo em que está trabalhando.
Observe que a limpeza de libc permite a marcação de alocações de memória heap em todo o sistema, bem como a verificação das tags para operações de memória dentro de libc.so
. Isso pode capturar bugs mesmo em binários nos quais o HWASan não foi habilitado se o acesso ruim à memória estiver em libc.so
(ex. pthread_mutex_unlock()
em um delete()
ed mutex).
Não é necessário alterar nenhum arquivo de construção se toda a plataforma for construída usando HWASan.
Flashstation
Para fins de desenvolvimento, você pode atualizar uma compilação de AOSP habilitada para HWASan em um dispositivo Pixel com bootloader desbloqueado usando Flashstation . Selecione o destino _hwasan, por exemplo, aosp_flame_hwasan-userdebug. Consulte a documentação do NDK para HWASan para desenvolvedores de aplicativos para obter mais detalhes.
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 precisar desenrolar por meio do código gerenciado, defina HWASAN_OPTIONS=fast_unwind_on_malloc=0
no ambiente do processo. Observe que os rastreamentos de pilha de acesso incorreto à memória usam o desbobinador "lento" por padrão; essa configuração afeta apenas os rastreamentos de alocação e desalocação. Essa opção pode exigir muito da CPU, dependendo da carga.
simbolização
Consulte Simbologia em "Entendendo os relatórios HWASan".
HWASan em aplicativos
Semelhante ao AddressSanitizer, o HWASan não pode ver o código Java, mas pode detectar bugs nas bibliotecas JNI. Até o Android 14, a execução de aplicativos HWASan em um dispositivo não HWASan não era compatível.
Em um dispositivo HWASan, os aplicativos podem ser verificados com HWASan criando seu código com SANITIZE_TARGET:=hwaddress
em Make ou -fsanitize=hwaddress
em sinalizadores de compilador. Em um dispositivo não HWASan (executando o Android 14 ou mais recente), uma configuração de arquivo wrap.sh LD_HWASAN=1
deve ser adicionada. Consulte a documentação do desenvolvedor do aplicativo para obter mais detalhes.