Nick Craver e Marc Gravell do Stack Exchange revelaram detalhes de uma falha crítica no compilador RyuJIT, parte do pacote .NET 4.6 que é distribuído junto com o Visual Studio 2015 e .NET base do Windows 10. Craver e Gravell identificaram como origem do bug, um problema na maneira como RyuJIT trata Tail Call Optimization. O resultado é que "... o método que chamamos não recebeu os parâmetro que passamos", e como os autores apontam, isso poderia ter consequências drásticas se as variáveis afetadas forem referentes a valores críticos.
Como resultado dessa descoberta, Matt Mitchell da Microsoft submeteu um patch (através de um pull request) que corrige o problema. Curiosamente, uma correção para esse bug havia sido aplicada e removida três dias atrás (24 de julho) por outro desenvolvedor da Microsot. Craver afirma que a presença deste bug não é facilmente identificável por várias razões:
- Acontece apenas quando otimizações estão habilitadas. Para maioria dos desenvolvedores e projetos isso não acontece em modo DEBUG e não vai aparecer localmente, o que significa que encontrará o problema apenas no modo RELEASE, o que na maioria dos casos é usado para por o sistema em produção;
- Habilitar o depurador altera o comportamento, quase sempre escondendo o problema;
- Adicionar uma chamada para Debug. WriteLine(), frequentemente, corrige o problema devido a mudança no tail.
É importante observar que mesmo quando a correção é aceita no repositório GitHub, o problema poder persistir - novos binários devem ser distribuídos pela Microsoft para usuários com .NET 4.6 instalado. Craver recomenda que desenvolvedores que ainda não implantaram .NEt 4.6 em produção, não o façam até que binários corrigidos estejam disponíveis. Se tiver o .NET 4.6 instalado (independente do tipo de ambiente) Craver recomenda desabilitar RyuJIT imediatamente e instruí como fazê-lo apresentando o código de uma prova de conceito. Também é importante saber, que a falha pode afetar programas desenvolvidos para versões anteriores do runtime .NET uma vez que é relacionada ao compilador RyuJIT.
Resposta da Microsoft (Atualizado em 28-7-2015)
Rich Lander da Microsoft respondeu formalmente ao informe feito por Craver e Gravell. Lander informa que apenas processos rodando em 64-bits são afetados pela falha - processos rodando em 32-bits não são afetados. Lande informa que sua equipe não considera que a falha seja explorável, mas ainda sim a equipe está trabalhando em uma correção como se fosse.
A orientação de Lander recomenda especificamente que o RyuJIT seja desabilitado até que a correção esteja disponível para quem estiver usando o framework .NET 4.6. De qualquer forma, dado o tempo gasto pra encontrar problemas, pode valer a pena investigar se este bug é causa de situações específicas uma vez que podem haver outras causas para comportamentos inesperados em outra aplicação.
De acordo com Lander, desenvolvedores F# tem mais chance de se deparar com as consequências desse bug e, assim sendo, não devem instalar o .NET 4.6, se possível. Lander disponibilizou exemplos de códigos que reproduzem o bug tanto no C# como no F#. Não foi informada uma data para disponibilização de um binário corrigido.