← Back to context

Comment by heinrich5991

2 days ago

Rust enables overflow checking in debug mode, you can (and I do) enable it in release mode as well.

Rust's default integer overflow in release mode is defined as well, it'll just wrap around. This makes it less likely to result in a vulnerability (unless you start writing unsafe Rust).

Additionally, integer overflow is less immediately dangerous in Rust, because buffer access is bounds-checked after the arithmetic. You can still get some logic bugs that eventually lead to vulnerabilities, but it's not an arbitrary memory write gadget.

  • What convinced me that this is wishful thinking was CVE-2023-53156. Yes, it used "unsafe" but the wraparound in release defeated the manual check, and when you aim for performance comparable to C, Rust tends to be full of unsafe blocks.

    IMHO better C tooling would be a far better investment than rewriting in Rust.

    • Incremental/quantitative improvement isn't disproven by contradiction. Anecdote is not data. Look at a bigger dataset, e.g. https://github.com/rust-fuzz/trophy-case there's a ton of overflows that result in caught panics or OOMs, and not bypasses. It works to reduce defect rate and severity.

      Note that C's tools for this like Valgrind, instrumented allocators and LLVM sanitizers work with Rust too. Investment in catching these in C generally helps unsafe Rust too, but Rust also has Miri, and a much better baseline for static analysis.

... do `unsafe {}` blocks not have the same semantics? I thought that was only about memory safety. Or are you thinking of cases where a wrapped-around integer gets interpreted as a pointer or something?

  • unsafe never changes the semantics of anything. Unsafe gives you access to additional features, never changes the meaning of a feature.