Depuração e mitigação de erros de memória

O Android tem suporte a várias ferramentas para depuração de erros de memória. Cada uma delas tem vantagens e desvantagens. Por isso, leia abaixo para decidir qual é a melhor para seu caso de uso. Este documento fornece uma visão geral das ferramentas disponíveis para que você possa decidir qual investigar melhor, mas tem como objetivo ser sucinto. Portanto, leia os documentos específicos de cada ferramenta para saber mais detalhes.

Texto longo, leia o resumo

  • Use uma linguagem segura para a memória sempre que possível para impedir a ocorrência de erros de memória
  • Sempre use PAC/BTI para mitigar ataques de ROP/JOP
  • Sempre use GWP-ASan para detectar erros raros de memória na produção
  • Use HWASan para detectar erros de memória durante testes
  • Dispositivos compatíveis com MTE não estão amplamente disponíveis em 2023, mas quando disponíveis, podem ser usados detectar erros na produção
  • Use ASan durante testes somente como último recurso

Linguagens seguras para a memória

Uma linguagem segura para a memória é a única maneira de evitar e mitigar completamente erros de memória. As outras ferramentas citadas nesta página podem ajudar a aumentar a segurança e confiabilidade de um código não seguro, mas o uso de uma linguagem segura para a memória elimina toda a classe de problemas.

As linguagens seguras para a memória com suporte oficial do Android são Java e Kotlin. É mais fácil desenvolver a maioria dos apps Android em uma dessas linguagens.

Dito isso, há desenvolvedores que enviam códigos em Rust, e se você está lendo esta página, provavelmente tem uma boa razão para precisar de código nativo (portabilidade, desempenho ou ambos). Rust é a melhor escolha para código nativo seguro para memória no Android. A equipe do NDK nem sempre conseguirá resolver os problemas que você enfrentar se seguir esse caminho, mas estamos interessados em ouvir sobre eles.

PAC/BTI

Autenticação de ponteiro e Identificação de destino da ramificação, também conhecidas como PAC/BTI, são ferramentas de mitigação adequadas para uso na produção. Embora sejam tecnologias separadas, elas são controladas pela mesma flag do compilador e, por isso, são sempre usadas juntas.

Esses recursos são compatíveis com versões anteriores dispositivos que não têm suporte a eles porque as novas instruções usadas estão inativas nesses dispositivos. Também é necessário ter um kernel e uma versão do SO que sejam bem recentes. Ao procurar paca e bti em /proc/cpuinfo, você descobre se tem um hardware e um kernel suficientemente atualizados. O Android 12 (nível 31 da API) oferece o suporte necessário ao espaço do usuário.

Vantagens:

  • Pode ser ativado em todos os builds, sem causar problemas em dispositivos ou kernels mais antigos. No entanto, faça o teste em uma combinação de dispositivo/kernel/SO que ofereça suporte

Desvantagens:

  • Disponível apenas para apps de 64 bits
  • Não mitiga erros em dispositivos sem suporte
  • 1% de sobrecarga de tamanho do código

GWP-Asan

GWP-ASan pode ser usado para detectar erros de memória no campo, mas a taxa de amostragem é muito baixa para ser uma mitigação eficaz.

Vantagens:

  • Sem sobrecarga significativa na CPU ou na memória
  • Implantação simples: não requer a recriação de código nativo
  • Funciona para apps de 32 bits

Desvantagens:

  • A baixa taxa de amostragem exige que um grande número de usuários encontre bugs de forma eficaz
  • Detecta apenas erros de heap, não de pilha

HWASan

O Limpador de endereços de hardware, também conhecido como HWASan, é a melhor opção para capturar erros de memória durante os testes. Essa ferramenta é mais útil quando usada com testes automatizados, especialmente se você estiver executando testes de fuzz. No entanto, dependendo das necessidades de desempenho do app, ela também pode ser usada em smartphones de última geração em uma configuração dogfood.

Vantagens:

  • Nenhum falso positivo
  • Detecta outras classes de erros que ASan não consegue (uso de pilha após o retorno)
  • Menor taxa de falsos negativos em relação à MTE (1 em 256 x 1 em 16)
  • Menor sobrecarga de memória do que ASan, a alternativa mais próxima

Desvantagens:

  • Sobrecarga significativa de CPU (aprox. 100%), tamanho do código (aprox. 50%) e memória (10% a 35%)
  • Até o nível 34 da API e o NDK r26, exige a instalação de uma imagem compatível com HWASan
  • Só funciona em apps de 64 bits

MTE

A Memory Tagging Extension, também conhecida como MTE, é uma alternativa de baixo custo ao HWASan. Além de recursos de depuração e teste, ele pode ser usado para detectar e mitigar a corrupção de memória na produção. Ative-o se você tiver o hardware para testar builds da MTE.

Vantagens:

  • Baixa sobrecarga necessária para ser tolerável na produção de muitos apps
  • Nenhum falso positivo
  • Não requer a recriação do código para detectar erros de heap, mas detecta os de pilha

Desvantagens:

  • Não há dispositivos comercialmente disponíveis com a MTE ativada por padrão em 2024, mas a documentação do Arm explica como ativar a MTE para testes no Pixel 8/Pixel 8 Pro.
  • Taxa de falso negativo de 1 em 16 em comparação com uma taxa de 1 em 256 do HWASan
  • Disponível apenas para apps de 64 bits
  • Exige a criação de bibliotecas separadas para uso em dispositivos com e sem MTE

ASan

O Limpador de endereços, também conhecido como ASan, é a ferramenta mais antiga e mais amplamente disponível. Ele é útil para detectar erros de memória durante problemas de teste e depuração que afetam apenas dispositivos antigos em que nenhuma das outras ferramentas está disponível. Sempre que possível, prefira usar o HWASan.

Vantagens:

  • Amplamente disponível Pode funcionar em dispositivos com versões antigas do Android, como KitKat
  • Não há falsos positivos ou negativos quando usado corretamente

Desvantagens:

  • Dificuldade de criar e empacotar corretamente
  • Maior sobrecarga entre todas as opções: aproximadamente 100% de CPU, aproximadamente 50% de tamanho do código e aproximadamente 100% de uso da memória
  • Não há mais suporte ao ASan
  • Ele tem bugs conhecidos que não serão corrigidos