Foi lançado o Rust 1.81, uma linguagem de programação de propósito geral desenvolvida originalmente pela Mozilla, mas agora mantida pela independente e sem fins lucrativos Rust Foundation. A linguagem se concentra em segurança no gerenciamento de memória e oferece ferramentas para alcançar alta paralelização na execução de tarefas, sem depender de um coletor de lixo e runtime (o runtime se restringe à inicialização básica e à manutenção da biblioteca padrão).
Os métodos de manipulação de memória em Rust protegem o desenvolvedor de erros ao trabalhar com ponteiros e evitam problemas decorrentes de manipulação de memória de baixo nível, como acesso a áreas de memória após sua liberação, desreferenciação de ponteiros nulos, e estouro de buffer, entre outros. Para distribuição de bibliotecas, construção e gerenciamento de dependências, o projeto conta com o gerenciador de pacotes Cargo. O repositório crates.io é suportado para hospedagem de bibliotecas.
A manipulação segura da memória em Rust é garantida em tempo de compilação através da verificação de referências, rastreamento de propriedade de objetos, controle do tempo de vida dos objetos (escopos) e avaliação da correção do acesso à memória durante a execução do código. Rust também oferece mecanismos para proteção contra estouros inteiros, exige a inicialização obrigatória de valores de variáveis antes do uso, trata erros de forma superior 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.
Principais novidades:
- O trait core::error::Error foi estabilizado, definindo as descrições de erros geradas. A mudança permite o uso de um único trait Error em várias bibliotecas, independentemente do ambiente, incluindo bibliotecas não vinculadas à biblioteca padrão, que usam o atributo «#![no_std]».
- As funções de ordenação estáveis e instáveis na biblioteca padrão foram adaptadas para usar novos algoritmos, demonstrando maior velocidade de execução e menor tempo de compilação. Na implementação dos novos algoritmos de ordenação, foi garantido a identificação de traits Ord mal definidos e o retorno de erros (panic) nesses casos, em vez de dados agrupados aleatoriamente.
- Uma nova camada de verificação "expect" ("#[expect(lint)]") foi implementada no linter, permitindo verificar se a verificação foi realizada e gerar um aviso caso não tenha sido (devido a um erro na implementação ou desativação da verificação). Por exemplo, ao migrar a base de código para usar a verificação undocumented_unsafe_blocks via Clippy, pode-se especificar "#[expect(clippy::undocumented_unsafe_blocks)]" para garantir que todos os blocos unsafe sejam documentados durante a transição. O Clippy também implementou verificações clippy::allow_attributes e clippy::allow_attributes_without_reason, simplificando a substituição do atributo «#[allow]» por «#[expect(lint)]».
- Foi possibilitada a documentação da razão para substituições nas camadas de verificação (lint), oferecendo aos novos desenvolvedores informações sobre os motivos que levaram à adição de determinada verificação, apresentadas como mensagens do compilador. Por exemplo: #![deny(clippy::float_arithmetic, reason = "no hardware float support")]
- Uma nova leva de APIs foi traduzida para a categoria estável, incluindo estabilizações de métodos e implementações de traits:
- core::error
- hint::assert_unchecked
- fs::exists
- AtomicBool::fetch_not
- Duration::abs_diff
- IoSlice::advance
- IoSlice::advance_slices
- IoSliceMut::advance
- IoSliceMut::advance_slices
- PanicHookInfo
- PanicInfo::message
- PanicMessage
O sinal "const", que determina a possibilidade de uso em qualquer contexto em vez de constantes, é aplicado em funções:
- char::from_u32_unchecked (função)
- char::from_u32_unchecked (método)
- CStr::count_bytes
- CStr::from_ptr
O tipo std::panic::PanicInfo foi renomeado para std::panic::PanicHookInfo (a funcionalidade do nome antigo será mantida, mas a partir da próxima versão, seu uso resultará em um aviso). O core::panic::PanicInfo permanecerá inalterado, mas será desenvolvido como um tipo separado. A separação dos tipos permitirá a implementação de diferentes métodos, específicos para a execução em contexto snd e no_std.
- Foi concluída a transição para o ABI C-unwind (‘extern «C-unwind»‘), que difere do ABI sem o sufixo «-unwind» (‘extern «C»‘) ao manter o comportamento seguro (safe), caso o processo de ‘unwinding’ iniciado por uma falha do programa ou pela geração de exceção no estilo C++ atravesse a fronteira do ABI (por exemplo, quando uma exceção que ocorre em código de uma linguagem de programação, durante o ‘unwinding’, afete a pilha associada a código de outra linguagem de programação). A partir da versão Rust 1.81, o ABI ‘extern «C»‘ utilizará falhas de segurança em casos de ‘unwinding’ não capturado.
- Nível três de suporte foi implementado para as plataformas i686-unknown-redox, xtensa-esp32-none-elf, xtensa-esp32s2-none-elf, xtensa-esp32s3-none-elf, xtensa-esp32-espidf, xtensa-esp32s2-espidf, xtensa-esp32s3-espidf. O nível três implica suporte básico, mas sem testes automatizados, publicação de builds oficiais e verificação da capacidade de compilar código.
- Nível dois de suporte foi implementado para as plataformas alvo loongarch64-unknown-linux-musl e arm64ec-pc-windows-msvc. O nível dois de suporte implica garantia de compilação.
- Um conjunto completo de ferramentas e um profiler foram fornecidos para sistemas Linux na plataforma LoongArch.
- Uma vulnerabilidade (CVE-2024-43402) foi corrigida em std::process::Command, manifestando-se apenas na plataforma Windows e eliminando um caminho de exploração de uma vulnerabilidade anteriormente corrigida, BatBadBut, relacionada ao tratamento de caracteres especiais ao usar chamadas Command::arg e Command::args, projetadas para transmissão direta de argumentos ao processo, sem processamento pelo interpretador de comandos. Na prática, ao executar scripts bat e cmd, o processo cmd.exe era iniciado, apresentando sua própria lógica de divisão de argumentos. O bypass de segurança baseia-se no fato de que o Windows remove espaços em branco e pontos iniciais em caminhos, ou seja, um arquivo com a extensão ‘.bat. .’ é tratado como ‘.bat’.
Além disso, podemos mencionar a saída de Wedson Almeida Filho do cargo de mantenedor do projeto Rust for Linux, que se dedica à introdução de recursos para desenvolvimento em Rust no núcleo do Linux. Após a saída de Wedson, o projeto conta com mais dois mantenedores: Miguel Ojeda, autor e principal desenvolvedor do Rust-for-Linux, e Alex Gaynor, ex-diretor da Python Software Foundation, que agora se dedica à promoção do Rust. O mantenedor que deixou o projeto, que se uniu há quatro anos, é funcionário da Microsoft e autor de um driver experimental que implementa o sistema de arquivos EXT2, escrito em Rust. Ultimamente, o trabalho de Almeida se concentrou na criação de ferramentas para desenvolvimento de sistemas de arquivos em Rust. Este ano, Almeida fez 17 commits no repositório Rust-for-Linux (para comparação, Miguel Ojeda fez 53 commits).
A razão mencionada para a saída é a falta de energia e entusiasmo que antes eram suficientes para lidar com alguns disparates não técnicos. Segundo Almeida, os desenvolvedores são forçados a gastar muito esforço em discussões sobre questões insignificantes, que minam um objetivo global mais importante. Almeida continua acreditando que o futuro dos núcleos está na utilização de linguagens que garantam uma operação segura com a memória, e se a comunidade de desenvolvedores do Linux não entender isso, o Linux será substituído por outro núcleo, assim como aconteceu com o Unix.
Os defensores do projeto Rust-for-Linux enfrentaram a necessidade de superar a resistência de desenvolvedores experientes do núcleo que não veem a necessidade de aprender uma nova linguagem. Em sua carta de renúncia, Almeida menciona como exemplo uma discussão que ocorreu durante sua apresentação junto com Kent Overstreet na conferência "Linux Storage, Filesystem, Memory-Management, and BPF Summit", que estava dedicada ao uso do Rust para desenvolvimento de sistemas de arquivos. A iniciativa de implementação do Rust foi criticada por Ted Ts'o, autor dos sistemas de arquivos ext2/ext3/ext4, que comparou a iniciativa Rust-for-Linux a uma tentativa de forçar todos a aceitar a religião Rust.
Em resposta à intenção de Almeida de criar uma camada sobre as interfaces de sistemas de arquivos escritas em C para seu uso em código Rust, Ted Ts'o apontou que tal camada inevitavelmente levará a problemas, já que qualquer alteração nas interfaces em C e a realização de refatoração exigirão mudanças na camada para Rust e ele não quer assumir a responsabilidade adicional por corrigir problemas que possam surgir no código Rust e monitorar o estado da camada Rust. O código em C está em constante evolução e, se sua alteração prejudicar o funcionamento da camada para Rust, isso comprometerá o funcionamento de todos os sistemas de arquivos vinculados a essa camada.
Ted também considera que, em um futuro próximo, a camada para Rust permanecerá em segundo plano e que surgirem problemas nos bindings será uma dor de cabeça apenas para os desenvolvedores Rust-for-Linux, e não para a comunidade de desenvolvedores de sistemas de arquivos no núcleo. Foi mencionado que nem todos os desenvolvedores estão dispostos a estudar Rust, e portanto, após implementarem mudanças que afetem outro código, eles poderão atualizar apenas o código dependente em C, mas não conseguirão corrigir as camadas Rust, pois não conhecem Rust. James Bottomley, responsável pela subsistema SCSI, também se juntou à discussão, dizendo que quanto mais semântica for codificada nas camadas, mais frágeis elas se tornam em termos de garantir a sincronização.
Enquanto isso, a empresa Google, que no ano passado reescreveu em Rust o firmware pvmfm, utilizado em máquinas virtuais, executados na plataforma Android, compartilhou-se a experiência de incorporar gradualmente código em Rust em firmware existente, originalmente escrito em C ou C++. Demonstrou-se como é possível aumentar significativamente a segurança do firmware, criando componentes substitutos com funcionalidade idêntica, escritos em Rust. A atenção principal ao implementar Rust deve ser direcionada ao uso de Rust para novos códigos e para aqueles críticos em termos de segurança (por exemplo, código que trata dados externos recebidos de fontes não confiáveis). Para integrar código em Rust e C, sugere-se usar camadas (shim) que traduzem chamadas entre APIs em Rust e C (a API C é exportada para uso no código em Rust e vice-versa), permitindo reescrever partes da API em Rust de forma gradual.
Fonte: opennet.ru
