Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can GCC's ASAN provide the same memory safety as Rust?

Rust is known as a memory-safe language, but there is a security feature in GCC called AddressSanitizer (ASAN):

./configure CFLAGS="-fsanitize=address -g" CXXFLAGS="-fsanitize=address -g" LDFLAGS="-fsanitize=address"
make
make check

Could ASAN provide the same memory safety as Rust, or does Rust have more tricks? Is it even possible to compare the two?

Disclaimer: I am not a programmer.

like image 299
Hessnov Avatar asked Feb 20 '18 20:02

Hessnov


People also ask

Is Rust really memory-safe?

Rust is a multi-paradigm, general-purpose programming language. Rust emphasizes performance, type safety, and concurrency. Rust enforces memory safety—that is, that all references point to valid memory—without requiring the use of a garbage collector or reference counting present in other memory-safe languages.

Is Zig memory-safe language?

Zig is memory-safe if you keep runtime checks enabled (e.g. with debug or release-safe optimization levels) but it does not have the compile-time guarantees of Rust.

What is a memory-safe language?

Memory safety is a property of some programming languages that prevents programmers from introducing certain types of bugs related to how memory is used. Since memory safety bugs are often security issues, memory safe languages are more secure than languages that are not memory safe.


1 Answers

The sanitizers

Both GCC and Clang have a suite of sanitizers; up until now, they were developed in Clang and then ported to GCC, so Clang has the most advanced versions:

  • Address Sanitizer (ASan): detects out-of-bounds access, use-after-free, use-after-scope, double-free/invalid-free and is adding support for memory leaks (expected memory overhead 3x),
  • Memory Sanitizer (MemSan): detects uninitialized reads (expected slow-down 3x),
  • Thread Sanitizer (TSan): detects data-races (expected slow-down 5x-15x, memory overhead 5x-10x),
  • Undefined Behavior Sanitizer (UBSan): various local undefined behaviors such as unaligned pointers, integral/floating point overflows, etc... (minimal slow-down, slight code size increase).

There is also work ongoing on a Type Sanitizer.


Sanitizers vs Rust

Unfortunately, bringing C++ up to Rust's level of safety with sanitizers is not possible; even combining all existing sanitizers would still leave gaps, they are known to be incomplete.

You can see John Regher's presentation on Undefined Behavior at CppCon 2017, the slides can be found on github, from which we get the current coverage:

enter image description here

And that is not accounting for the fact that sanitizers are incompatible with each others. That is, even if you were willing to accept the combined slow-down (15x-45x?) and memory overhead (15x-30x?), you would still NOT manage for a C++ program to be as safe as a Rust one.


Hardening vs Debugging

The reason sanitizers are so CPU/memory hungry is because they are debugging tools; they attempt to give developers as precise a diagnostic as possible, so as to be most useful for debugging.

For running code in production, what you are looking for is hardening. Hardening is about eliminating Undefined Behavior with as low an overhead as possible. Clang, for example, supports multiple ways to harden a binary:

  • Control Flow Integrity (CFI): protects against control-flow hi-jacking (virtual calls, indirect calls, ...),
  • Safe Stack: protects against stack buffer overflows, aka Return Oriented Programming,
  • Undefined Behavior Sanitizer.

Those tools can be combined and have minimal (< 1%) performance impact. They cover much less ground than sanitizers, unfortunately, and most notably do not attempt to cover use-after-free/use-after-scope or data-races which are frequent targets of attacks.


Conclusion

I do not see any way to bring C++ up to the level of safety that Rust combines, without either:

  • very serious restrictions on the language: see MISRA/JSF guidelines,
  • very serious loss of performance: sanitizers, disabling optimizations, ...
  • a complete overhaul of the standard library and coding practices, of which the Core Guidelines are a start.

On the other hand, it is worth noting that Rust itself uses unsafe code; and its unsafe code also needs to be vetted (see Rust Belt project) and would benefit from all the above sanitizers/hardening instrumentation passes.

like image 160
Matthieu M. Avatar answered Oct 01 '22 09:10

Matthieu M.