Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] gcc/g++ default flags for Habitat builds #587

Open
ghost opened this issue May 28, 2017 · 9 comments
Open

[RFC] gcc/g++ default flags for Habitat builds #587

ghost opened this issue May 28, 2017 · 9 comments

Comments

@ghost
Copy link

ghost commented May 28, 2017

I am wondering if any thought has been given to maybe setting default compile flags for gcc/g++. I know one of the use cases for Habitat is increased security and it appears that other package maintainers have these as part of their standard like https://fedoraproject.org/wiki/Changes/Harden_All_Packages.

Just food for thought!

@ghost
Copy link
Author

ghost commented May 29, 2017

Thanks @reset. I would have brought this up in the Slack channel but felt it may be worth preserving the conversation in GitHub as it may wind up in broad sweeping change if implemented ...

@stevendanna
Copy link
Contributor

stevendanna commented May 30, 2017

I'm +1 on improving the default flags used throughout core-plans. core-plans should provide artifacts that balance speed, security, and debug-ability.

Some things we may want to consider:

  • gcc -fstack-protector-strong
  • gcc -O2 (or some other default optimization level)
  • gcc -g (although we strip symbols later anyway, so maybe not)
  • gcc -­fPIE
  • gcc ­D_FORTIFY_SOURCE=2
  • gcc ­-Wformat -­Wformat­security
  • ld -­z relro
  • ld -z now
  • ld ­-pic

stevendanna added a commit to stevendanna/core-plans that referenced this issue Oct 21, 2017
The desired for more robust default build flags was raised in
habitat-sh#587. The goal of this build is to add a couple
of tools to make it easier to start investigating hardening
core-plans:

 - a shell script that can be included in plans to enable
   compiler- and linker-level security features.

 - a new bin/check-security-feature.sh script can be used
   to check that the resulting package actually has the features in the
   compiled executables.

Currently, we include the following flags:

- `-fstack-protector-strong`
- `-Wl,-z,relro`
- `-Wl,-z,now`
- `-D_FORTIFY_SOURCE=2 -O2`

For details on these flags, see in source comments.

* Possible Future Work

I've excluded PIE-related flags for now because I've found them hard
to set generally via CFLAGS.  It may be easier to pursue PIE builds
with a gcc built with `--default-enable-pie`.

Another often-used set of flags are format-security warning flags.
These flags would be useful if and only if we have a plan to maintain
patches to fix the warnings or contribute fixes upstream.

For information on what other large distributions do:

- https://wiki.debian.org/Hardening
- https://wiki.gentoo.org/wiki/Project:Hardened
- https://fedoraproject.org/wiki/Changes/Harden_All_Packages

Signed-off-by: Steven Danna <[email protected]>
stevendanna added a commit to stevendanna/core-plans that referenced this issue Oct 22, 2017
The desired for more robust default build flags was raised in
habitat-sh#587. The goal of this build is to add a couple
of tools to make it easier to start investigating hardening
core-plans:

 - a shell script that can be included in plans to enable
   compiler- and linker-level security features.

 - a new bin/check-security-feature.sh script can be used
   to check that the resulting package actually has the features in the
   compiled executables.

Currently, we include the following flags:

- `-fstack-protector-strong`
- `-Wl,-z,relro`
- `-Wl,-z,now`
- `-D_FORTIFY_SOURCE=2 -O2`

For details on these flags, see in source comments.

* Possible Future Work

I've excluded PIE-related flags for now because I've found them hard
to set generally via CFLAGS.  It may be easier to pursue PIE builds
with a gcc built with `--default-enable-pie`.

Another often-used set of flags are format-security warning flags.
These flags would be useful if and only if we have a plan to maintain
patches to fix the warnings or contribute fixes upstream.

For information on what other large distributions do:

- https://wiki.debian.org/Hardening
- https://wiki.gentoo.org/wiki/Project:Hardened
- https://fedoraproject.org/wiki/Changes/Harden_All_Packages

Signed-off-by: Steven Danna <[email protected]>
@eeyun eeyun added the C-RFC label Nov 9, 2017
@eeyun eeyun changed the title [QUESTION] gcc/g++ default flags for Habitat builds [RFC] gcc/g++ default flags for Habitat builds Nov 9, 2017
@eeyun
Copy link
Contributor

eeyun commented Nov 16, 2017

I'm definitely +1 on this in concept. But I have some feedback and a request. I think a change like this that (if implemented) touches a significant portion of the packages in core needs to undergo the newly defined RFC process. That process right now is outlined in an actual RFC that's undergoing it's own RFC process (meta, right?). That being said I'd like to get some core plans maintainership feedback on this but I would prefer that this get closed and resubmitted following that process.

I know this has been open for quite some time and I'm sorry it's taken so long for us to get any kind of reasonable feedback on it. @pantocrator27 or @stevendanna if you still feel passionately about this change would either of you be willing to spearhead the RFC effort around this?

@stevendanna
Copy link
Contributor

@eeyun I submitted a PR here to add some tooling into core-plans to make it possible to incrementally add these flags to builds: #881

I'm happy to do an RFC; however, there is an extent to which I think an incremental approach and gathering information might be preferable to setting policy since we have a lot to learn still.

@eeyun
Copy link
Contributor

eeyun commented Nov 17, 2017

@stevendanna I could totally see that. I'm all for an incremental approach the only challenge is any changes against the default flags with either of these packages are going to touch like 90% of the world. We can adopt incrementally but we might need to talk about what that looks like in implementation/test? All of this to say, I trust you and if you've got ideas about how to do it you've 100% got my support.

@bdangit
Copy link
Contributor

bdangit commented Nov 17, 2017

👍 for security. Would like to see how many of our plans would be affected by these extra flags and this could be accomplished if we ran your security script against any plans that require gcc or maybe all of the binaries.

stevendanna added a commit that referenced this issue Nov 19, 2017
The desired for more robust default build flags was raised in
#587. The goal of this build is to add a couple
of tools to make it easier to start investigating hardening
core-plans:

 - a shell script that can be included in plans to enable
   compiler- and linker-level security features.

 - a new bin/check-security-feature.sh script can be used
   to check that the resulting package actually has the features in the
   compiled executables.

Currently, we include the following flags:

- `-fstack-protector-strong`
- `-Wl,-z,relro`
- `-Wl,-z,now`
- `-D_FORTIFY_SOURCE=2 -O2`

For details on these flags, see in source comments.

* Possible Future Work

I've excluded PIE-related flags for now because I've found them hard
to set generally via CFLAGS.  It may be easier to pursue PIE builds
with a gcc built with `--default-enable-pie`.

Another often-used set of flags are format-security warning flags.
These flags would be useful if and only if we have a plan to maintain
patches to fix the warnings or contribute fixes upstream.

For information on what other large distributions do:

- https://wiki.debian.org/Hardening
- https://wiki.gentoo.org/wiki/Project:Hardened
- https://fedoraproject.org/wiki/Changes/Harden_All_Packages

Signed-off-by: Steven Danna <[email protected]>
stevendanna added a commit to stevendanna/core-plans that referenced this issue Nov 19, 2017
The desire for more robust default build flags was raised in
habitat-sh#587. The goal of this change is to add a couple
of tools to make it easier to start investigating hardening
core-plans:

 - a shell script that can be included in plans to enable
   compiler- and linker-level security features.

 - a new bin/check-security-feature.sh script can be used
   to check that the resulting package actually has the features in the
   compiled executables.

Currently, we include the following flags:

- `-fstack-protector-strong`
- `-Wl,-z,relro`
- `-Wl,-z,now`
- `-D_FORTIFY_SOURCE=2 -O2`

For details on these flags, see the in-source comments.

* Possible Future Work

I've excluded PIE-related flags for now because I've found them hard
to set generally via CFLAGS. It may be easier to pursue PIE builds
with a gcc built with `--default-enable-pie`.

Another often-used set of flags are format-security warning flags.
These flags would be useful if and only if we have a plan to maintain
patches to fix the warnings or contribute fixes upstream.

For information on what other large distributions do:

- https://wiki.debian.org/Hardening
- https://wiki.gentoo.org/wiki/Project:Hardened
- https://fedoraproject.org/wiki/Changes/Harden_All_Packages

Signed-off-by: Steven Danna <[email protected]>
@lilianmoraru
Copy link
Contributor

I have been doing this for almost a year on my habitat origins(I really didn't like that all the packages are compiled without any optimizations).
While I customize per package, here are some general flags that will work for every package:

$ export RUSTFLAGS="-C target-cpu=x86-64"

# "-Wno-error -Wno-error=implicit-fallthrough" - newer GCCs throw more warnings and some packages treat warnings as errors
$ export CFLAGS="-O3 -DNDEBUG -fomit-frame-pointer -ftree-vectorize -march=x86-64 -pipe -Wno-error -Wno-error=implicit-fallthrough"

# lzop is the only package limited to gnu++11, without it "-std=gnu++14" will also work
$ export CXXFLAGS="-std=gnu++11 -O3 -DNDEBUG -fomit-frame-pointer -ftree-vectorize -march=x86-64 -pipe -Wno-error -Wno-error=implicit-fallthrough"
$ export CPPFLAGS="-pipe -Wno-error -Wno-error=implicit-fallthrough"

A few more points(these could probably easily be used and then in do_prepare to remove the flags from the environment variables, per package):

  • export LDFLAGS="-Wl,-Bsymbolic-functions -Wl,-z,relro" works on everything except busybox
  • export CXXFLAGS="-std=gnu++14" works on everything except lzop
  • export CFLAGS/CXXFLAGS="-fstack-protector-strong" works on everything except: gcc, glibc, grub, valgrind

Addressing some of the flags @stevendanna mentioned:

  • D_FORTIFY_SOURCE=2 will fail to compile on a lot of packages
  • ­-Wformat -­Wformat­security because a good amount of packages treat warnings as errors, this will probably fail a lot of them, also, throwing a warning does not improve the final binary.
  • -z now full relro is hard to introduce, most packages fail with it.
  • -­fPIE/-pic is hard to use correctly "globally" because these need to apply only to executables(PIE) or only to libraries(PIC) - a project can compile multiple libraries and then link them into an executable(you cannot decide whether to use PIE or PIC).

@stevendanna
Copy link
Contributor

@lilianmoraru Thanks for all of the awesome info. I made a quick stab at adding some of these flags in #881 but didn't apply it nearly as generally as have.

-z now full relro is hard to introduce, most packages fail with it.

What kind of failures have you seen here? I haven't hit any but I've only rebuild a handful of simple package.

-­fPIE/-pic is hard to use correctly "globally" because these need to apply only to executables(PIE) or only to libraries(PIC) - a project can compile multiple libraries and then link them into an executable(you cannot decide whether to use PIE or PIC).

Yup, I ended up punting on this as well. I think to apply this on a large scale we would have to go the route of some of the distributions and have pretty complicated wrappers to decide on the right gcc flags on a per-invocation basis.

@lilianmoraru
Copy link
Contributor

It seems I got some of the flags wrong there(I've revisited them and some work with relro for example).
You can see what I use here: https://github.com/be-plans/be
The flags are in defaults.sh and to search for disabled flags you need to search for be_remove_compiler_flag and be_remove_linker_flag.

For Habitat core plans I would recommend to avoid -O3 and -D_GNU_SOURCE(although ninja really loves that flag).
Projects that do not handle undefined behavior well in C/C++ projects, can hit bugs with -O3(I've not hit any issues with it yet).

I will actually apply later the flags cleaner, without an "out of source" script, so defaults.sh will disappear.

@dmccown dmccown added this to the 1.0 core plans milestone Dec 11, 2018
stevendanna added a commit to habitat-sh/core-plans-rfcs that referenced this issue Apr 30, 2020
Habitat's core plans should provide a reliable base system on which
Habitat users can build applications. To meet this goal, core-plans
software written in the C programming language should use compiler and
linker flags that provide a level of performance and security at least
as good as other Linux distributions.

Multiple users have attempted to make progress on this issue in the
past. For example,

- habitat-sh/core-plans#587
- habitat-sh/core-plans#881

and the lack of optimization was recently discussed in the Habitat
Slack.

NOTE FOR REVIEW: I took a "slow and steady" approach to implementing
this on the assumption that this would be mostly an effort that
happens outside the core Hab team. I think a faster path is possible.

Signed-off-by: Steven Danna <[email protected]>
stevendanna added a commit that referenced this issue Apr 30, 2020
Habitat's core plans should provide a reliable base system on which
Habitat users can build applications. To meet this goal, core-plans
software written in the C programming language should use compiler and
linker flags that provide a level of performance and security at least
as good as other Linux distributions.

Multiple users have attempted to make progress on this issue in the
past. For example,

#587
#881

and the lack of optimization was recently discussed in the Habitat
Slack.

NOTE FOR REVIEW: I took a "slow and steady" approach to implementing
this on the assumption that this would be mostly an effort that
happens outside the core Hab team. I think a faster path is possible.

Signed-off-by: Steven Danna <[email protected]>
stevendanna added a commit that referenced this issue May 4, 2020
Habitat's core plans should provide a reliable base system on which
Habitat users can build applications. To meet this goal, core-plans
software written in the C programming language should use compiler and
linker flags that provide a level of performance and security at least
as good as other Linux distributions.

Multiple users have attempted to make progress on this issue in the
past. For example,

#587
#881

and the lack of optimization was recently discussed in the Habitat
Slack.

NOTE FOR REVIEW: I took a "slow and steady" approach to implementing
this on the assumption that this would be mostly an effort that
happens outside the core Hab team. I think a faster path is possible.

Signed-off-by: Steven Danna <[email protected]>
@rahulgoel1 rahulgoel1 removed the V-devx label Jul 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants