Conversation

GrapheneOS used to implement a local-init sanitizer for Clang to zero uninitialized variables in C and C++. In the development branch, this feature is once again globally enabled for Vanadium and the GrapheneOS kernel/userspace via Clang's new -ftrivial-auto-var-init=zero switch.
2
31
Zero initialization is hidden behind -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang. We consider it part of the stable API regardless and depend on the feature. If it's removed, it will break compatibility with GrapheneOS and we'll just fork Clang again.
2
9
The existence of this switch is due to hostility by LLVM developers towards making existing C and C++ code safer. The desire for zeroing was misrepresented as being solely about performance. They're in denial about the unsafety of real world C and C++ code including within LLVM.
2
8
In the real world, C and C++ code makes pervasive use of uninitialized data and often depends on it being zeroed in practice. Initialization with a non-zero value is a dangerous backwards incompatible change. It regularly turns inert latent bugs into exploitable vulnerabilities.
2
7
Replying to
That sounds like a significant exaggeration. I agree zeroing yields increased safety in event of bugs, but no C code "depends on" it intentionally. No real world implementation except the clang option gives zeros; normally you get whatever was there last.
1
Replying to and
Mappings start out zeroed and it's a very common byte pattern. It's also not something covered by sanitizers in a way that's easy to use. Valgrind reports jumps based on uninitialized values but misses a lot and has many false positives with modern compilers so it's not usable.
1
Replying to
But in practice it's not zero, except with that clang option or maybe on first time stack reaches that depth. BTW I found some old uclinux minimal shell with such a bug. It blew up with dynamic linking because ldso had already used the stack.
1
Replying to
Overall, uninitialized data usually isn't zero, but it being zero is common enough that there are many cases where it's actually fairly reliably zero so that software somehow develops dependencies on it being zero. The dependency is often that there's one zero byte, not all zero.
1
1
Show replies