This is an archive of the discontinued LLVM Phabricator instance.

Allow using -ftrivial-auto-var-init=zero in C mode without extra flags
Needs ReviewPublic

Authored by glider on Jul 15 2019, 7:38 AM.

Details

Reviewers
jfb
Summary

Initially concerns have been raised that -ftrivial-auto-var-init=zero
potentially defines a new dialect of C++, therefore this option was
guarded with
-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang.

The guard flag name suggests that at some point
-ftrivial-auto-var-init=pattern will perform on par with
-ftrivial-auto-var-init=zero, thus making it possible to remove the
latter from Clang.
However this isn't going to happen in the nearest future, at least not
on X86, where memset(object, 0, size) is still lowered to a more
efficient code than memset(object, 0xAA, size).
Therefore security-minded people may still need an easy way to
zero-initialize all the locals to keep the performance penalty low.

For Linux kernel, which already uses a non-standard dialect of C,
introducing yet another hardening feature doesn't radically change the
situation. Other C codebases also tend to use non-standard features more
often, so the mentioned guard flag only complicates the adoption of
auto-initialization for them, not actually protecting their purity.

As a compromise solution, let
-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang
remain mandatory for -ftrivial-auto-var-init=zero in C++ mode and make
it optional in the C mode.

Event Timeline

glider created this revision.Jul 15 2019, 7:38 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 15 2019, 7:38 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
glider added a reviewer: jfb.Jul 15 2019, 7:41 AM
glider added subscribers: kcc, pcc, vitalybuka and 3 others.
jfb added a comment.Jul 15 2019, 11:54 AM

A lots of folks from the original discussion insisted on this as a compromise. I'd like to make sure they see and approve of this, they might have requests for e.g. specific performance numbers.

As a data point, Linus Torvalds suggested that we need a similar feature for GCC so that the "kernel C standard" mandates zero-initialization for locals: https://lkml.org/lkml/2019/7/28/206

jfb added a comment.Jul 30 2019, 9:19 AM

As a data point, Linus Torvalds suggested that we need a similar feature for GCC so that the "kernel C standard" mandates zero-initialization for locals: https://lkml.org/lkml/2019/7/28/206

Interesting!

Adding more people from the original discussion.

Folks, we're now stuck in a situation where there's a potential buy-in from the Linux kernel community for stack initialization, but they won't ever use an option guarded by -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang. On the other hand, using pattern initialization is still costly, and will probably remain such, as there are little investments into Clang's DSE. (The nature of pattern initialization also suggests there'll always be corner cases in which zero initialization is still cheaper).

As a data point, Linus Torvalds suggested that we need a similar feature for GCC so that the "kernel C standard" mandates zero-initialization for locals: https://lkml.org/lkml/2019/7/28/206

I'm wondering why they never pushed all the way for a -std=linux-c flag instead, and produced a documentation with the behavior they want with respect to the base C standard they align on.

As a data point, Linus Torvalds suggested that we need a similar feature for GCC so that the "kernel C standard" mandates zero-initialization for locals: https://lkml.org/lkml/2019/7/28/206

I'm wondering why they never pushed all the way for a -std=linux-c flag instead, and produced a documentation with the behavior they want with respect to the base C standard they align on.

Guess this was never necessary, as GCC used to be the only compiler that could build the Linux kernel, and the standard could be defined by a combination of GCC flags.
This is no more the case, but adding a separate "standard" (which may end up being vaguely defined and containing ad-hoc hacks) will require a lot of effort from the three communities (Linux, GCC and LLVM)