Updates to build flags #
- Date proposed: 2020-03-04
- RFC MR: https://gitlab.archlinux.org/archlinux/rfcs/-/merge_requests/0003
Summary #
Updating our buildflags will improve our packages security.
Motivation #
Compiler security features have advanced since we last updated our buildflags. While we have enabled some of these by default in our compilers, there is further improvements to be made.
This RFC puts forward a set of compiler flags that have seen real world usage in other distributions e.g. Fedora and Ubuntu.
Specification #
We will change the distributed makepkg.conf
to the following:
#CPPFLAGS=""
CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions \
-Wp,-D_FORTIFY_SOURCE=2,-D_GLIBCXX_ASSERTIONS -Werror=format-security \
-fstack-clash-protection -fcf-protection"
CXXFLAGS="$CFLAGS"
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
DEBUG_CFLAGS="-g -fvar-tracking-assignments"
Details of new additions:
-
Move
-D_FORTIFY_SOURCE=2
from CPPFLAGS to CFLAGS using -WpUnfortunately, there are still build systems which use CFLAGS but not CPPFLAGS. Or configure tests that use CPPFLAGS and not CFLAGS which creates errors due to fortify source needing optimisation. Ultimately, we can cover more code with this workaround.
-
Add
-fexceptions
Provide exception unwinding support for C programs. This also hardens cancellation handling in C programs, and makes it possible to unwind the stack (using C++ throw or Rust panics) from C callback functions.
-
Add
-Wp,-D_GLIBCXX_ASSERTIONS
Enable lightweight assertions in the C++ standard library. This flag is added to both CFLAGS and CXXFLAGS; C compilations will simply ignore it.
-
Add
-Werror=format-security
Turn on format string warnings and treat them as errors. This catches a set of readily exploitable bugs. This can occasionally result in compilation errors, but this should be minimal as it is widely used by other distributions.
-
Add
-fstack-clash-protection
Ensures all variable length memory allocated from the stack (via
alloca()
or GCC variable length arrays etc) are probed at the time they are allocated. This mitigates stack-clash attacks by ensuring all stack memory allocations are valid (or by raising a segmentation fault if they are not, and turning a possible code-execution attack into a denial of service). Without this flag, vulnerabilities can result where the stack overlaps with the heap, or thread stacks spill into other regions of memory. -
Add
-fcf-protection
Generates instructions to support Intel's Control-flow Enforcement Technology (CET). Instrument binaries to guard against ROP/JOP attacks. Used on
i686
andx86_64
.
Drawbacks #
Moving -D_FORTIFY_SOURCE=2
is zero cost.
Adding -Werror=format-security
may cause limited build issues, but patches are readily available.
There is a minimal performance overhead of adding -Wp,-D_GLIBCXX_ASSERTIONS
, though many of the added checks are optimised away by the compiler.
Adding -fstack-clash-protection
also has very little run-time overhead.
Adding -fexceptions
can produce some data size overhead in C programs, though does not affect execution.
GCC enables it by default for C++.
Using -fcf-protection
is incompatible with -mindirect-branch
(which is used to implement retpoline
).
In such cases it is recommended to disable -fcf-protection
, such as with -fcf-protection=none
in CFLAGS/CXXFLAGS.
Unresolved Questions #
None.
Alternatives Considered #
-
Add
-grecord-gcc-switches
to our debug buildsThis is the default in GCC.
-
Add
-fasynchronous-unwind-tables
to our debug buildsThis is the default in GCC, at least for x86_64.