Ponteiros com tag

A partir do Android 11, para processos de 64 bits, todas as alocações de heap têm uma tag definida de implementação definida no byte superior do ponteiro em dispositivos com suporte do kernel para ARM Top-byte Ignore (TBI). Qualquer app que modifique isso tag é finalizada quando é verificada durante a desalocação. Isso é necessário para hardware futuro compatível com a Extensão ARM Memory Tagging Extension (MTE).

Ignorar byte superior

O recurso "Ignorar bytes superiores" do ARM está disponível para código de 64 bits em todo o hardware Armv8 AArch64. Esse recurso significa que o hardware ignora o byte superior de um ponteiro ao ao acessar a memória.

A TBI requer uma versão compatível kernel que processa corretamente ponteiros com tags passados do espaço do usuário. Os kernels comuns do Android a partir da versão 4.14 (Pixel 4) e versões mais recentes apresentam o TBI necessário patches.

Os dispositivos com suporte a TBI no kernel são detectados dinamicamente em horário de início do processo, e uma tag dependente da implementação é inserida byte do ponteiro para todas as alocações de heap. Depois disso, é feita uma verificação Verifique se a tag não foi truncada ao desalocar a memória.

Prontidão da Memory Tagging Extension

A Memory Tagging Extension (MTE) da ARM ajuda a resolver problemas de segurança da memória. MTE funciona marcando os 56o a 59o bits de endereço de cada memória alocação na pilha, no heap e nos globais. Hardware e conjunto de instruções verifica automaticamente se a tag correta é usada em cada acesso à memória.

Apps Android que armazenam informações incorretamente no byte superior do do aplicativo têm certeza de ser interrompida em um dispositivo com MTE ativado. Os ponteiros com tag facilitam a detecção e a rejeição de usos incorretos da parte superior byte do ponteiro antes que os dispositivos MTE estejam disponíveis.

Suporte para desenvolvedores

Se o app falhou e esse link foi solicitado a você, isso pode significar uma das seguintes opções:

  1. O app tentou liberar um ponteiro que não foi alocado pelo alocador de heap do sistema.
  2. Alguma coisa no seu app modificou o byte superior de um ponteiro. O byte superior o ponteiro não pode ser modificado e seu código precisa ser alterado para corrigir isso problema.

Exemplos de ponteiro de byte superior sendo usado ou modificado incorretamente.

  • Os ponteiros para um tipo específico têm metadados específicos do app armazenados nos 16 bits de endereço principais.
  • Um ponteiro convertido em duplo e depois voltar, perdendo os bits de endereço inferiores.
  • Cálculo de código da diferença entre os endereços de variáveis locais de diferentes frames de pilha como forma de medir a profundidade da recursão.

Alguns aplicativos podem depender de bibliotecas que se comportam incorretamente quando a para o byte superior do ponteiro. Reconhecemos que pode ser muito difícil corrigir esses problemas nas bibliotecas rapidamente. Assim, Apps que usam targetSdkLevel < 30 a inclusão de tag de ponteiro não vai ser ativada por padrão. Também oferecemos uma fuga hatch para apps criados com targetSdkLevel >= 30 para facilitar o período de transição.

A saída de emergência é usada adicionando o seguinte ao seu Arquivo AndroidManifest.xml:

  <application android:allowNativeHeapPointerTagging="false">
  ...
  </application>

Isso desativa o recurso de marcação do ponteiro do seu app. Isso não aborda problema subjacente de integridade do código. Essa saída de emergência vai desaparecer no futuro do Android, pois problemas dessa natureza serão incompatíveis com MTE (link em inglês).