Jann Horn, da equipe do Google Project Zero, que uma vez identificou as vulnerabilidades Spectre e Meltdown, publicou uma técnica para explorar uma vulnerabilidade (CVE-2021-4083) no coletor de lixo do kernel Linux. A vulnerabilidade se deve a uma condição de corrida ao limpar descritores de arquivos em soquetes Unix e potencialmente permite que um usuário local sem privilégios execute seu código no nível do kernel.
O problema é interessante porque a janela de tempo durante a qual a condição de corrida ocorre foi estimada como sendo muito pequena para criar explorações reais, mas o autor do estudo mostrou que mesmo essas vulnerabilidades inicialmente céticas podem se tornar a fonte de ataques reais se o criador da exploração tiver as habilidades e o tempo necessários. Yann Horn mostrou como, com a ajuda de manipulações de filigrana, você pode reduzir a condição de corrida que ocorre ao chamar as funções close() e fget() simultaneamente em uma vulnerabilidade de uso após liberação totalmente explorável e obter acesso a dados já liberados estrutura dentro do kernel.
Uma condição de corrida ocorre durante o processo de fechamento de um descritor de arquivo ao chamar close() e fget() ao mesmo tempo. A chamada para close() pode ocorrer antes da execução de fget(), o que confundirá o coletor de lixo porque, de acordo com o refcount, a estrutura do arquivo não terá referências externas, mas permanecerá anexada ao descritor do arquivo, ou seja, O coletor de lixo pensará que tem acesso exclusivo à estrutura, mas na verdade, por um curto período de tempo, a entrada restante na tabela de descritores de arquivo ainda apontará para a estrutura sendo liberada.
Para aumentar a probabilidade de entrar em condição de corrida, foram utilizados vários truques, que permitiram aumentar a probabilidade de sucesso da exploração para 30% ao introduzir otimizações específicas do sistema. Por exemplo, para aumentar o tempo de acesso a uma estrutura com descritores de arquivo em várias centenas de nanossegundos, os dados foram expulsos do cache do processador, enchendo o cache com atividades em outro núcleo da CPU, o que tornou possível recuperar a estrutura da memória em vez de de o rápido cache da CPU.
A segunda característica importante foi o uso de interrupções geradas por um temporizador de hardware para aumentar o tempo de condição de corrida. O momento foi selecionado para que o manipulador de interrupção fosse acionado quando ocorresse uma condição de corrida e interrompesse a execução do código por algum tempo. Para atrasar ainda mais o retorno do controle, foram geradas cerca de 50 mil entradas na fila de espera por meio do epoll, o que exigia busca no manipulador de interrupções.
A técnica para explorar a vulnerabilidade foi divulgada após um período de sigilo de 90 dias. O problema aparece desde o kernel 2.6.32 e foi corrigido no início de dezembro. A correção foi incluída no kernel 5.16 e também foi transferida para ramificações LTS do kernel e pacotes de kernel fornecidos em distribuições. Vale ressaltar que a vulnerabilidade foi identificada durante a análise de um problema semelhante CVE-2021-0920, que se manifesta no coletor de lixo ao processar a flag MSG_PEEK.
Fonte: opennet.ru