Consulte Noções básicas sobre os relatórios do HWASan para informações sobre como ler falhas do HWASan.
O AddressSanitizer com suporte de 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 só está disponível no Android 10 e versões mais recentes, e apenas em hardware AArch64.
Embora seja útil principalmente para código C/C++, o HWASan também pode ajudar a depurar o código Java que causa falhas em C/C++ usado para implementar interfaces Java. Ele é útil porque detecta erros de memória quando eles acontecem, apontando diretamente para o código responsável.
Em comparação com o ASan clássico, o HWASan tem:
- Sobrecarga de CPU semelhante (~2x)
- Sobrecarga de tamanho de código semelhante (40 a 50%)
- Sobrecarga de RAM muito menor (10% a 35%)
O HWASan detecta o mesmo conjunto de bugs do ASan:
- Overflow/underflow do buffer de heap e pilha
- Uso de heap depois da liberação de memória
- Uso de pilha fora do escopo
- Double free/wild free
Além disso, o HWASan detecta o uso da pilha após o retorno.
O HWASan (assim como o ASan) é compatível com o UBSan, os dois podem ser ativados em um destino ao mesmo tempo.
Detalhes e limitações da implementação
O HWASan é baseado na abordagem de inclusão de tags na memória, em que um pequeno valor de tag aleatório é associado a ponteiros e intervalos de endereços de memória. Para que um acesso à memória seja válido, as tags de ponteiro e de memória precisam corresponder. O HWASan depende do recurso de byte superior ignorado (TBI, na sigla em inglês) do ARMv8, também chamado de inclusão de tags de endereço virtual, para armazenar a tag de ponteiro nos bits mais altos do endereço.
Leia mais sobre o design do HWASan no site de documentação do Clang.
Por design, o HWASan não tem as redzones de tamanho limitado do ASan para detectar overflows 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 overflow ou há quanto tempo a memória foi desalocada. Isso dá ao HWASan uma grande vantagem sobre o ASan.
No entanto, o HWASan tem um número limitado de valores de tag possíveis (256), o que significa que há uma probabilidade de 0,4% de perder qualquer bug durante uma execução do programa.
Requisitos
As versões recentes (4.14 ou mais recentes) do kernel comum do Android oferecem suporte ao HWASan. As ramificações específicas do Android 10 não têm suporte para HWASan.
O suporte ao 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 exigirá que o kernel do Linux aceite ponteiros marcados em argumentos de chamada do sistema. O suporte para isso foi implementado nos seguintes patchsets upstream:
- ABI de endereço marcado arm64
- arm64: desmarcar ponteiros de usuário transmitidos ao kernel
- mm: evitar a criação de aliases de endereço virtual em brk()/mmap()/mremap()
- arm64: validar endereços marcados em access_ok() chamados de threads do kernel
Se você estiver criando com uma cadeia de ferramentas personalizada, verifique se ela inclui tudo até o commit c336557f do LLVM.
Usar o HWASan
Use os comandos a seguir para criar toda a plataforma usando o HWASan:
lunch aosp_walleye-userdebug # (or any other product)export SANITIZE_TARGET=hwaddressm -j
Para sua conveniência, você pode adicionar a configuração SANITIZE_TARGET a uma definição de produto, semelhante a aosp_coral_hwasan.
Para usuários familiarizados com o AddressSanitizer, muita complexidade de build desapareceu:
- Não é necessário executar a criação duas vezes.
- Os builds incrementais funcionam imediatamente.
- Não é necessário fazer o flash de userdata.
Algumas restrições do AddressSanitizer também desapareceram:
- Os executáveis estáticos são aceitos.
- Não há problema em ignorar a higienização de qualquer destino que não seja libc. Ao contrário do ASan, não há requisito de que, se uma biblioteca for higienizada, qualquer executável que a vincule também precise ser.
A troca entre imagens HWASan e imagens normais no mesmo número da versão (ou superior) pode ser feita livremente. Não é necessário limpar o dispositivo.
Para ignorar a higienização de um módulo, use
LOCAL_NOSANITIZE := hwaddress (Android.mk) ou
sanitize: { hwaddress: false } (Android.bp).
Higienizar destinos individuais
O HWASan pode ser ativado por destino em um build normal (não higienizado), desde que libc.so também seja
higienizado. Adicione hwaddress: true ao bloco de higienização em "libc_defaults"
em bionic/libc/Android.bp. Em seguida, faça o mesmo no destino em que você está trabalhando.
A higienização do libc permite a inclusão de tags de alocações de memória de heap em todo o sistema, bem como a
verificação das tags para operações de memória dentro de libc.so. Isso pode detectar bugs mesmo em binários
em que o HWASan não estava ativado se o acesso à memória ruim estiver em libc.so
(por exemplo, pthread_mutex_unlock() em um mutex delete()ed).
Não é necessário mudar nenhum arquivo de build se toda a plataforma for criada usando o HWASan.
Melhores stack traces
O HWASan usa um unwinder rápido baseado em ponteiro de frames para gravar um stack
trace para cada evento de alocação e desalocação de memória no
programa. O Android ativa os ponteiros de frames no código AArch64 por padrão,
então isso funciona muito bem na prática. Se você precisar desenrolar o código gerenciado, defina HWASAN_OPTIONS=fast_unwind_on_malloc=0
no ambiente do processo. Os stack traces de acesso à memória ruim usam o unwinder "lento" por padrão. Essa configuração afeta apenas os traces de alocação e desalocação. Essa opção pode ser muito
intensiva em termos de CPU, dependendo da carga.
Simbolização
Consulte Simbolização em "Noções básicas sobre os relatórios do HWASan".
HWASan em apps
Semelhante ao AddressSanitizer, o HWASan não pode acessar o código Java, mas pode detectar bugs nas bibliotecas JNI. Até o Android 14, a execução de apps HWASan em um dispositivo não HWASan era não aceita.
Em um dispositivo HWASan, os apps podem ser verificados com o HWASan criando o código deles com SANITIZE_TARGET:=hwaddress em Make ou -fsanitize=hwaddress em flags do compilador.
Em um dispositivo não HWASan (executando o Android 14 ou mais recente), um arquivo wrap.sh que define
LD_HWASAN=1 precisa ser adicionado.
Consulte a
documentação para desenvolvedores de apps
para mais detalhes.