A partir do Android 11, para processos de 64 bits, todas as alocações de heap têm uma tag definida pela implementação definida no byte superior do ponteiro em dispositivos com suporte de kernel para ARM Top-byte Ignore (TBI). Qualquer aplicativo que modifique essa tag é encerrado quando a tag é verificada durante a desalocação. Isso é necessário para hardware futuro com suporte ARM Memory Tagging Extension (MTE).
Ignorar byte superior
O recurso Top-byte Ignore do ARM está disponível para código de 64 bits em todos os hardwares Armv8 AArch64. Esse recurso significa que o hardware ignora o byte superior de um ponteiro ao acessar a memória.
O TBI requer umkernel compatível que manipule corretamente os ponteiros marcados passados do espaço do usuário. Os kernels comuns do Android da versão 4.14 (Pixel 4) e superior apresentam os patches TBI necessários.
Dispositivos com suporte a TBI no kernel são detectados dinamicamente na hora de início do processo e uma tag dependente de implementação é inserida no byte superior do ponteiro para todas as alocações de heap. Depois disso, uma verificação é executada para garantir que a tag não tenha sido truncada ao desalocar a memória.
Prontidão da extensão de marcação de memória
A Memory Tagging Extension (MTE) do ARM ajuda a resolver problemas de segurança de memória. O MTE funciona marcando o 56º-59º bits de endereço de cada alocação de memória na pilha, heap e globais. O hardware e o conjunto de instruções verificam automaticamente se o tag correto é usado em cada acesso à memória.
Aplicativos Android que armazenam informações incorretamente no byte superior do ponteiro têm garantia de falha em um dispositivo habilitado para MTE . Os ponteiros marcados facilitam a detecção e a rejeição de usos incorretos do byte superior do ponteiro antes que os dispositivos MTE estejam disponíveis.
Suporte ao desenvolvedor
Se seu aplicativo travou e você foi solicitado com este link, isso pode significar um dos seguintes:
- O aplicativo tentou liberar um ponteiro que não foi alocado pelo alocador de heap do sistema.
- Algo em seu aplicativo modificou o byte superior de um ponteiro. O byte superior do ponteiro não pode ser modificado e seu código precisa ser alterado para corrigir esse problema.
Exemplos do ponteiro de byte superior sendo usado ou modificado incorretamente.
- Os ponteiros para um tipo específico têm metadados específicos do aplicativo armazenados nos 16 bits de endereço principais.
- Um ponteiro converte para dobrar e depois voltar, perdendo os bits de endereço mais baixos.
- Código computando a diferença entre os endereços de variáveis locais de diferentes quadros de pilha como forma de medir a profundidade da recursão.
Alguns aplicativos podem depender de bibliotecas que se comportam incorretamente quando o byte superior do ponteiro é definido. Reconhecemos que pode não ser trivial corrigir rapidamente esses problemas subjacentes nas bibliotecas. Como tal, os aplicativos que usam targetSdkLevel < 30
não terão a marcação de ponteiro habilitada por padrão. Também fornecemos uma saída de emergência para aplicativos criados com targetSdkLevel >= 30
para facilitar o período de transição.
A escotilha de escape é usada adicionando o seguinte ao seu arquivo AndroidManifest.xml
:
<application android:allowNativeHeapPointerTagging="false"> ... </application>
Isso desativará o recurso Marcação de ponteiro para seu aplicativo. Observe que isso não resolve o problema de integridade do código subjacente. Essa escotilha de escape desaparecerá em futuras versões do Android, pois problemas dessa natureza serão incompatíveis com o MTE .