A memória não inicializada em C e C++ é uma causa comum de problemas de confiabilidade, bugs de segurança de memória e vazamentos de informações. Para evitar esses problemas, o Android inicializa o máximo de memória possível.
Memória do espaço do usuário inicializada em zero
No Android 12 e versões mais recentes, a memória da pilha é inicializada em zero
em todo o código nativo da plataforma (incluindo JNI), e a memória heap é inicializada em zero
em todos os processos nativos da plataforma (como netd),
mas não na zygote ou em apps.
É altamente recomendável que apps próprios e de terceiros criados com o NDK
usem a flag do compilador -ftrivial-auto-var-init=zero para inicializar as variáveis locais da
pilha a zero. O compilador otimiza qualquer zero desnecessário.
Por exemplo, quando uma variável local é inicializada explicitamente
(como a variável int x = 123; x é inicializada apenas uma vez).
Se o programa tiver um buffer de pilha grande em um ponto de acesso
de desempenho, o desenvolvedor poderá desativar a inicialização usando um atributo
do compilador:
__attribute__((__uninitialized__)) char buf[BUFSIZ];
Os apps também podem ativar a inicialização de pilha zero usando o
atributo de manifesto android:nativeHeapZeroInitialized.
Como alternativa, a inicialização do heap zero pode ser controlada no momento da execução
com:
int mallopt(M_BIONIC_ZERO_INIT, level)
Em que o nível é 0 ou 1.
Memória do kernel inicializada como zero
A pilha e o heap do kernel são inicializados em zero para kernels do GKI, o que é recomendado pelo CDD.
Para a inicialização da pilha, o GKI usa a
configuração CONFIG_INIT_STACK_ALL_ZERO, que resulta na criação do
kernel usando a flag do compilador -ftrivial-auto-var-init=zero.
Para a inicialização do heap, o GKI usa o
CONFIG_INIT_ON_ALLOC_DEFAULT_ON, que faz com que todas as alocações de heap de página, SLAB
e SLUB sejam inicializadas em zero quando são criadas. Essa opção é
semelhante a transmitir init_on_alloc=1 como uma opção
de inicialização do kernel.
Relatórios de bugs
Nossas ferramentas geram relatórios de bugs úteis que contêm informações adicionais para ajudar na depuração. O rastreamento de pilha de alocação e desalocação adicional ajuda a entender melhor o ciclo de vida de uma determinada alocação e leva a bugs de segurança de memória raiz muito mais rapidamente.
Durante o desenvolvimento, os fornecedores precisam monitorar a presença de bugs verificando
/data/tombstones e
logcat para falhas nativas. Para mais informações sobre
a depuração de código nativo do Android, consulte as informações aqui.