Como os CVEs de segurança de memória diferem entre Rust e C/C++
Rust, comportamento indefinido e unsafe
- Alguns argumentam que UB pode ocorrer em Rust sem usar diretamente
unsafeno seu crate: viano_std, falhas de correção da linguagem, UB em dependências ou na biblioteca padrão, ou bugs do compilador/LLVM. - Outros enfatizam o modelo do Rust: a UB precisa se originar em algum
unsafeem algum lugar (incluindo em dependências ou na std); a vantagem é queunsafefica localizado e pode ser revisado.
Semântica de overflow de inteiros
- Há disputa sobre o comportamento do Rust de “panic no debug, wrap no release”.
- Críticos dizem que ter dois comportamentos torna o overflow praticamente tão pouco confiável quanto UB e gostariam que o overflow sempre causasse panic.
- Outros ressaltam que isso é definido pela implementação, não UB: o comportamento é limitado e configurável (
overflow-checks = true), ao contrário da UB em C/C++ que pode levar a otimizações incorretas extremas.
Como interpretar CVEs de Rust
- Bibliotecas Rust tendem a tratar qualquer uso incorreto que possa causar UB como um CVE, mesmo que a exploração seja irrealista.
- Ecossistemas C/C++ raramente classificam esses problemas como CVEs, então o número bruto de “CVEs” é visto como uma métrica enganosa para a segurança de uma linguagem.
- Alguns temem que isso possa se estender a panics serem tratados como vulnerabilidades de DoS; outros veem isso como parte de uma cultura que prioriza correção.
Prevalência e importância de bugs de segurança de memória
- Um comentarista afirma que bugs de memória são uma fração minúscula das vulnerabilidades “médias”; outros contestam isso e citam dados (na própria thread) de que problemas de segurança de memória dominam zero-days de alto impacto.
- Há debate sobre se portar grandes bases de código para Rust seria uma sobre-otimização ou algo justificado para software de alto valor e muito atacado (navegadores, componentes de sistema operacional, Android).
Estratégias de segurança em Rust vs C++ moderno
- Um lado argumenta que C++ moderno, junto com bibliotecas fortalecidas, sanitizers e guidelines, pode em grande parte resolver bugs de memória se usado de forma consistente.
- Contra-argumentos:
- Na prática, muitas bases grandes em C/C++ continuam inseguras (Android, Chromium, bibliotecas de sistema).
- A segurança é o padrão em Rust; em C++ ela costuma exigir opt-in, disciplina cuidadosa e toolchains que as equipes frequentemente afrouxam sob pressão de entrega.
- Relatos do mundo real (por exemplo, Android) são citados como evidência de que Rust gera grandes reduções em vulnerabilidades de memória em comparação com código legado em C/C++.
Nulls, assertions e contratos
- Discussão em torno de funções como
curl_getenve se deve haver assert para entradas nulas. - Alguns defendem verificações de pré-condição em todo lugar; outros argumentam que, em C, isso vira ruído e muitas vezes descamba para “crash de qualquer forma em uma dereferência nula”.
- O
Option<T>do Rust e referências não nulas são contrastados: APIs precisam optar explicitamente porNone, e o uso incorreto leva a panics com backtraces claros em vez de UB.
Desempenho e tendências de adoção
- Exemplos como a reescrita do parser HTML do Ladybird mostram Rust substituindo C++ com desempenho igual ou melhor.
- Há debate sobre se os ganhos de velocidade vêm do Rust em si ou das oportunidades de redesenho durante as reescritas.
- C e C++ são vistos como perdendo espaço em alguns domínios (navegadores, kernels), embora muitos domínios (HPC, HFT, stacks orientadas por padrões) ainda girem em torno de C/C++.
Complexidade do Rust e preocupações com dependências
- Críticos destacam a complexidade conceitual do Rust (ownership, lifetimes, tipos avançados) e o esforço gasto para moldar tipos a fim de satisfazer o borrow checker.
- Defensores enquadram isso como “tornar a complexidade explícita” em vez de escondê-la, produzindo código mais seguro e mais fácil de depurar.
- Há preocupação ampla com grandes árvores profundas de dependências em Rust (stdlib enxuta, muitos crates,
build.rs, publicação atrelada ao GitHub) e o risco correspondente de supply chain. - Defensores observam que C/C++ muitas vezes “resolvem” isso fazendo vendor ou copy-paste de código, o que obscurece as dependências em vez de eliminá-las.