Consulte Noções básicas sobre os relatórios do HWASan para informações sobre como ler falhas do HWASan.
O Limpador de endereços 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 só está disponível no Android 10 e versões mais recentes, e apenas em hardware AArch64.
Embora seja principalmente útil para código C/C++, o HWASan também pode ajudar a depurar código Java que causa falhas em C/C++ usado para implementar interfaces Java. Ele é útil porque captura erros de memória quando eles acontecem, apontando diretamente para o código responsável.
Atualize as imagens HWASan pré-criadas para dispositivos Pixel com suporte em ci.android.com (instruções detalhadas de configuração).
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 (igual ao ASan) é compatível com o UBSan, e ambos 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 a 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 ser correspondentes. O HWASan depende do recurso de ignorar bytes principais (TBI, na sigla em inglês) do recurso ARMv8, também chamado de inclusão de tags de endereço virtual, para armazenar a tag do 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 zonas vermelhas de tamanho limitado do ASan para detectar transbordamentos ou a quarentena de capacidade limitada do ASan para detectar uso após a liberação. Por esse motivo, o HWASan pode detectar um bug independentemente do tamanho do overflow ou de quanto tempo atrás 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 são compatíveis com o HWASan. As ramificações específicas do Android 10 não têm suporte para HWASan.
A compatibilidade com o espaço do usuário para o HWASan está disponível a partir do Android 11.
Se você estiver trabalhando com um kernel diferente, o HWASan exige que o kernel do Linux aceite ponteiros marcados em argumentos de chamada de sistema. O suporte a isso foi implementado nos seguintes conjuntos de patches upstream:
- ABI de endereço com tag arm64
- arm64: remover a tag dos ponteiros do usuário transmitidos para o kernel
- mm: Avoid creating virtual address aliases in brk()/mmap()/mremap()
- arm64: validar endereços marcados em access_ok() chamado de linhas de execução do kernel
Se você estiver compilando com um conjunto de ferramentas personalizado, verifique se ele inclui tudo até a confirmação do LLVM c336557f.
Usar o HWASan
Use os comandos abaixo para criar toda a plataforma usando o HWASan:
lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -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 do build foi eliminada:
- Não é necessário executar o make duas vezes.
- Builds incrementais funcionam imediatamente.
- Não é necessário atualizar o userdata.
Algumas restrições do AddressSanitizer também foram removidas:
- Os executáveis estáticos são compatíveis.
- Não é necessário limpar nenhum destino, exceto a libc. Ao contrário do ASan, não há a exigência de que, se uma biblioteca for limpa, todos os executáveis que a vinculam também precisam ser limpos.
A alternância entre o HWASan e imagens regulares no mesmo número de build (ou superior) pode ser feita livremente. Não é necessário limpar o dispositivo.
Para pular a limpeza de um módulo, use
LOCAL_NOSANITIZE := hwaddress
(Android.mk) ou
sanitize: { hwaddress: false }
(Android.bp).
Limpar destinos individuais
O HWASan pode ser ativado por destino em um build regular (não higienizado), desde que libc.so
também seja
higienizado. hwaddress: true
foi adicionado ao bloco de limpeza em "libc_defaults"
em bionic/libc/Android.bp. Em seguida, faça o mesmo no destino em que você está trabalhando.
A desinfecção da libc permite a inclusão de tags em alocações de memória do heap em todo o sistema, além da
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 foi ativado se o acesso de memória inválido 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.
FlashStation
Para fins de desenvolvimento, é possível atualizar um build do AOSP com suporte a HWASan em um dispositivo Pixel com o carregador de inicialização desbloqueado usando a Flashstation. Selecione o destino _hwasan, por exemplo, aosp_flame_hwasan-userdebug. Consulte a documentação do NDK do HWASan para desenvolvedores de apps para saber mais.
Stack traces melhores
O HWASan usa um unwinder rápido baseado em ponteiro de frame para registrar um stack
trace para cada evento de alocação e desalocação de memória no
programa. O Android ativa ponteiros de frame 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. Os stack traces de acesso à memória inválidos usam o desbobinador "lento" por padrão. Essa configuração afeta apenas os traces de alocação e desalocação. Essa opção pode consumir muita CPU, dependendo da carga.
Simbolização
Consulte Simulação em "Noções básicas sobre os relatórios do HWASan".
HWASan em apps
Assim como o AddressSanitizer, o HWASan não pode acessar o código Java, mas pode detectar bugs nas bibliotecas JNI. Até o Android 14, não era possível executar apps HWASan em um dispositivo que não fosse HWASan.
Em um dispositivo HWASan, os apps podem ser verificados com o HWASan criando o
código com SANITIZE_TARGET:=hwaddress
no
Make ou -fsanitize=hwaddress
em sinalizações do compilador.
Em um dispositivo não HWASan (com Android 14 ou mais recente), é necessário adicionar uma configuração de arquivo wrap.sh
LD_HWASAN=1
.
Consulte a documentação do desenvolvedor de apps para mais detalhes.