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 esta tag será encerrado quando a tag for verificada durante a desalocação. Isso é necessário para hardware futuro com suporte para 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 todo o hardware Armv8 AArch64. Este recurso significa que o hardware ignora o byte superior de um ponteiro ao acessar a memória.
O TBI requer um kernel compatível que lide corretamente com ponteiros marcados passados do espaço do usuário. Os kernels comuns do Android 4.14 (Pixel 4) e superiores apresentam os patches TBI necessários.
Dispositivos com suporte TBI no kernel são detectados dinamicamente no momento de início do processo e uma tag dependente da implementação é inserida no byte superior do ponteiro para todas as alocações de heap. Depois disso, é executada uma verificação para garantir que a tag não foi truncada ao desalocar a memória.
Prontidão da extensão de marcação de memória
A Memory Tagging Extension (MTE) da ARM ajuda a resolver problemas de segurança de memória. O MTE funciona marcando os bits de endereço 56 a 59 de cada alocação de memória na pilha, heap e globais. O conjunto de hardware e instruções verifica automaticamente se o tag correto é usado em cada acesso à memória.
Os aplicativos Android que armazenam informações incorretamente no byte superior do ponteiro têm garantia de falha em um dispositivo habilitado para MTE . Ponteiros marcados facilitam a detecção e rejeição de usos incorretos do byte superior do ponteiro antes que os dispositivos MTE estejam disponíveis.
Suporte ao desenvolvedor
Se o seu aplicativo travou e você recebeu 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 no 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 de ponteiro de byte superior sendo usado ou modificado incorretamente.
- Ponteiros para um tipo específico possuem metadados específicos do aplicativo armazenados nos 16 bits de endereço principais.
- Um ponteiro convertido para dobrar e depois voltar, perdendo os bits de endereço inferiores.
- Código que calcula 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. Dessa forma, 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 Pointer Tagging para seu aplicativo. Observe que isso não resolve o problema de integridade do código subjacente. Essa saída de emergência desaparecerá em versões futuras do Android, pois problemas dessa natureza serão incompatíveis com o MTE .