Although I think all the C compilers are safe ish lately. I haven't seen exploits that target defects in output. Usually the error is ID10T located in the prekeyboard device.
The only problem is that these options are not the default and most C developers do not use them, especially for release versions.
I always use them, including for releases. In the relatively rare cases when this has a performance impact, I disable the sanitize options only for the functions where this matters and only after an analysis that guarantees that events like overflows or out-of-bounds accesses cannot happen.
Despite the hype, by default Rust is not safer than C compiled with the right options, because the default for Rust releases is also to omit many run-time checks.
Only when Rust will change the default to keep all run-time checks also in release builds, it will be able to claim that by default it is safer than C.
For now, when safety is desired, both C and Rust must be compiled with non-default options.
Which checks are you thinking of? The only thing that comes to mind is that integer overflow wraps instead of panics, but given that bounds are checked, it is still going to be a panic or logic bug rather than a buffer overflow.
1. Notably, some sanitizers are not intended for production use. I think this has changed a bit for asan but at one point it made vulns easier to exploit. These aren't mitigations.
2. They're extremely expensive. You need tons of bookkeeping for pointers for them to work. If you're willing to take that hit I don't really understand why you're using C, just use a GC'd language, which is probably going to be faster at that point.
> Only when Rust will change the default to keep all run-time checks also in release builds, it will be able to claim that by default it is safer than C.
The only thing Rust turns off at release is that unsigned integer overflows panic in debug but wrap on release. That wrap can not lead to memory unsafety.
I don't think anyone has built anything practically usable that is meant for production, though it wouldn't be impossible to do so.
But sometimes DoS is considered an exploit, and in that case you don't want to make things easier to crash.
...because the type system and borrow checker satisfies them at compile-time?
The only checks that are omitted at runtime are:
- checks that are exhaustively proven to be unnecessary by LLVM - checks that can never be triggered in the absence of UB
You shouldn't be triggering UB checks at runtime. If you rely on these checks, you're relying on UB itself, when all UB should be provably impossible.