A Google reescreveu o firmware pvmfm, utilizado no Android, na linguagem Rust

Como parte dos esforços para aumentar a segurança de componentes de software críticos na plataforma Android, a Google reescreveu o firmware pvmfm na linguagem Rust, utilizado para organizar o funcionamento de máquinas virtuais iniciadas pelo hypervisor pVM do Android Virtualization Framework. Anteriormente, o firmware era escrito na linguagem C e implementado sobre o bootloader U-Boot, no qual vulnerabilidades foram anteriormente encontradas devido a problemas com a memória.

O firmware reescrito em Rust foi incluído no Android 14, e as bibliotecas universais criadas durante o processo de desenvolvimento do firmware foram formatadas como pacotes crate e entregues à comunidade Rust. Por exemplo, foi publicado o pacote smccc para suportar interfaces ARM PSCI (Power State Coordination Interface) e chamadas SMCCC (SMC Calling Convention), e o pacote aarch64-paging para manipulação de tabelas de páginas de memória. Também foi realizada uma revisão de erros e expansão da funcionalidade do pacote existente virtio-drivers com implementação de drivers VirtIO. Além da plataforma Android, os pacotes mencionados estão envolvidos no projeto Oak, que desenvolve componentes para transmissão, armazenamento e processamento de dados em ambientes protegidos (TEE, Trusted Execution Environment).

O hypervisor pVM assume o controle em uma fase precoce do carregamento e garante completa isolamento de memória máquinas virtuais e do ambiente host, impedindo que o sistema host acesse as máquinas virtuais protegidas, nas quais são processados dados confidenciais. O firmware pvmfm (Protected Virtual Machine Firmware) obtém o controle logo após o início da máquina virtual, realiza a verificação do ambiente criado e decide sobre a interrupção de emergência do carregamento em caso de problemas com a integridade ou gera um certificado de inicialização para o sistema convidado em caso de confirmação da cadeia de confiança.

A reescrita na linguagem Rust permite uma aderência mais simples e segura à "regra dos dois", aplicada pelo Google para manter a segurança dos componentes do sistema Android. De acordo com essa regra, qualquer código adicionado deve atender a no máximo duas das três condições: lidar com dados não verificados, usar uma linguagem de programação não segura (C/C++) e ser executado com privilégios elevados. Dessa regra, deduz-se que o código para processar dados externos deve ser ou reduzido ao mínimo de privilégios (isolado) ou escrito em uma linguagem de programação segura. Segundo o Google, cerca de 70% de todas as vulnerabilidades perigosas identificadas no Android são causadas por erros relacionados à memória.

Rust é focada em operações seguras com memória e permite reduzir o risco de vulnerabilidades causadas por problemas como referências a áreas de memória após sua liberação e estouro de buffer. A segurança da memória em Rust é garantida durante a compilação através da verificação de referências, rastreamento da posse de objetos e consideração do tempo de vida dos objetos (escopos), assim como pela avaliação da correção do acesso à memória durante a execução do código. Rust também oferece ferramentas para proteção contra estouros inteiros, exige a inicialização obrigatória dos valores das variáveis antes do uso, gerencia melhor os erros na biblioteca padrão, aplica o conceito de referências e variáveis imutáveis (immutable) por padrão e oferece uma forte tipagem estática para minimizar erros lógicos.

Entre as dificuldades que surgem no processo de desenvolvimento de componentes de baixo nível em Rust, como drivers, está a necessidade de trabalhar com ponteiros brutos em modo unsafe, pois Rust é projetado levando em conta o uso da memória alocada no programa, e no código que opera sem camadas acima do hardware, é necessário acessar a memória compartilhada e MMIO. Atualmente, as capacidades de Rust para trabalhar com ponteiros brutos deixam a desejar, mas a situação deve mudar após a estabilização do suporte para os macros offset_of, slice_ptr_get e slice_ptr_len.

Entre as desvantagens, merece atenção a necessidade de uma sintaxe aprimorada para acessar campos de estruturas e índices de arrays através de ponteiros brutos, sem criar referências, além das limitações na criação de wrappers seguros sobre operações unsafe, que podem causar comportamentos indefinidos e não podem ser verificadas pelo compilador. Por exemplo, não é possível criar tais wrappers para operações com tabelas de páginas de memória, já que o mapeamento de páginas em uma parte do programa pode afetar outras partes.

Em relação ao tamanho do código resultante, a antiga versão do firmware pVM ocupava 220 kB, enquanto a nova ocupa 460 kB; no entanto, novas funcionalidades foram adicionadas à versão reescrita, permitindo a eliminação de alguns outros componentes utilizados na inicialização. Como resultado, o tamanho total de todos os componentes de inicialização antigos e novos ficou comparável. Observa-se que, quando o tamanho é mais importante que o desempenho, resultados comparáveis com a linguagem C podem ser alcançados ao habilitar modos de otimização de tamanho adicionais no compilador, eliminar dependências desnecessárias e não utilizar recursos de formatação de strings.

Adicionalmente, é mencionada a continuidade do trabalho na implementação da capacidade de execução de aplicações confiáveis escritas na linguagem Rust (Trusted Application) no sistema operacional Trusty, que fornece um ambiente TEE (Trusted Execution Environment) para Android, sendo executado em paralelo com o Android no mesmo processador em um ambiente isolado. O Trusty é utilizado em dispositivos Pixel e já emprega Rust em bibliotecas e componentes do sistema (o núcleo continua em C).

Fonte: opennet.ru

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster