How memory safety CVEs differ between Rust and C/C++
Rust, undefined behavior, and unsafe
- Some argue UB can occur in Rust without directly using
unsafein your crate: viano_std, language soundness holes, UB in dependencies or the standard library, or compiler/LLVM bugs. - Others emphasize Rust’s model: UB must originate in some
unsafesomewhere (including in dependencies or std); the benefit is thatunsafeis localized and reviewable.
Integer overflow semantics
- Dispute over Rust’s “panic in debug, wrap in release” behavior.
- Critics say having two behaviors makes overflow practically as unreliable as UB and wish overflow always panicked.
- Others stress this is implementation-defined, not UB: behavior is bounded and configurable (
overflow-checks = true), unlike C/C++ UB that can lead to extreme misoptimizations.
How to interpret Rust CVEs
- Rust libraries tend to treat any misuse that can cause UB as a CVE, even if exploitation is unrealistic.
- C/C++ ecosystems rarely classify such issues as CVEs, so raw “number of CVEs” is viewed as a misleading metric for language safety.
- Some worry this could extend to panics being treated as DoS vulnerabilities; others see it as part of a culture that prioritizes correctness.
Prevalence and importance of memory safety bugs
- One commenter claims memory bugs are a tiny fraction of “average” vulnerabilities; others dispute this and cite data (within the thread) that memory safety issues dominate high‑impact zero-days.
- There’s debate whether porting broad codebases to Rust is over‑optimization versus justified for high‑value, heavily attacked software (browsers, OS components, Android).
Rust vs modern C++ safety strategies
- One side argues modern C++ plus hardened libraries, sanitizers, and guidelines can largely solve memory bugs if used consistently.
- Counterpoints:
- In practice many large C/C++ codebases remain unsafe (Android, Chromium, system libraries).
- Rust’s safety is the default; in C++ safety often requires opting in, careful discipline, and toolchains that teams frequently relax under delivery pressure.
- Real‑world reports (e.g., Android) are cited as evidence Rust yields large reductions in memory vulnerabilities compared to legacy C/C++ code.
Nulls, assertions, and contracts
- Discussion around functions like
curl_getenvand whether to assert on null inputs. - Some advocate pervasive precondition checks; others argue that in C this becomes noisy and often devolves to “crash anyway on null deref.”
- Rust’s
Option<T>and non‑nullable references are contrasted: APIs must explicitly opt intoNone, and misuse leads to panics with clear backtraces rather than UB.
Performance and adoption trends
- Examples like Ladybird’s HTML parser rewrite show Rust replacing C++ with equal or better performance.
- Debate whether speed gains come from Rust itself or from redesign opportunities during rewrites.
- C and C++ are seen as losing ground in some domains (browsers, kernels), though many domains (HPC, HFT, standards‑driven stacks) still revolve around C/C++.
Rust complexity and dependency concerns
- Critics highlight Rust’s conceptual complexity (ownership, lifetimes, advanced types) and the effort spent shaping types to satisfy the borrow checker.
- Supporters frame this as “making complexity explicit” instead of hiding it, yielding safer, more debuggable code.
- There’s broad concern about large, deep dependency trees in Rust (thin stdlib, many crates,
build.rs, GitHub‑tied publishing) and corresponding supply‑chain risk. - Defenders note that C/C++ often “solve” this by vendoring or copy‑pasting code, which obscures dependencies rather than eliminating them.