0d16217
This document contains documentation of the individual compiler flags
0d16217
and how to use them.
0d16217
0d16217
[TOC]
0d16217
0d16217
# Using RPM build flags
0d16217
0d16217
At present, the only supported way is to use the `%configure` macro to
0d16217
obtain the full complement of flags, like this:
0d16217
0d16217
    %configure
0d16217
0d16217
This will invoke the `./configure` with arguments (such as
0d16217
`--prefix=/usr`) to adjust the paths to the packaging defaults.
0d16217
0d16217
As a side effect, this will set the environment variables `CFLAGS`,
0d16217
`CXXFLAGS`, `FFLAGS`, `FCFLAGS`, and `LDFLAGS`, so they can be used by
0d16217
makefiles and other build tools.
0d16217
0d16217
For some other build tools besides `autoconf`, separate mechanisms exist:
0d16217
0d16217
* CMake builds use the the `%cmake` macro from the `cmake-rpm-macros`
0d16217
  package.
0d16217
0d16217
Care must be taking not to compile the current selection of compiler
0d16217
flags into any RPM package besides `redhat-rpm-config`, so that flag
0d16217
changes are picked up automatically once `redhat-rpm-config` is
0d16217
updated.
0d16217
0d16217
# Flag selection for the build type
0d16217
0d16217
The default flags are suitable for building applications.
0d16217
0d16217
For building shared objects, you must compile with `-fPIC` in
0d16217
(`CFLAGS` or `CXXFLAGS`) and link with `-shared` (in `LDFLAGS`).
0d16217
0d16217
For other considerations involving shared objects, see:
0d16217
0d16217
* [Fedora Packaging Guidelines: Shared Libraries](https://fedoraproject.org/wiki/Packaging:Guidelines#Shared_Libraries)
0d16217
0d16217
# Customizing compiler flags
0d16217
0d16217
It is possible to set RPM macros to change some aspects of the
0d16217
compiler flags.  Changing these flags should be used as a last
0d16217
recourse if other workarunds are not available.
0d16217
0d16217
### Disable hardened builds
0d16217
0d16217
    %undefine _hardened_build
0d16217
0d16217
This turns off certain hardening features, as described in detail
0d16217
below.  The main difference is that executables will be
0d16217
position-dependent (no full ASLR) and use lazy binding.
0d16217
0d16217
### Disable annotated builds/watermarking
0d16217
0d16217
    %undefine _annotated_build
0d16217
0d16217
This turns off watermarking, making it impossible to do full hardening
0d16217
coverage analysis for any binaries produced.
0d16217
078af19
### Disable strict symbol checks in the link editor (ld)
078af19
078af19
By default, the link editor will refuse to link shared objects which
078af19
contain undefined symbols.  In some cases (such as when a DSO is
078af19
loaded as a plugin and is expected to bind to symbols in the main
078af19
executable), undefined symbols are expected.  In this case, you can
078af19
add
078af19
078af19
    %undefine _strict_symbol_defs_build
078af19
078af19
to the RPM spec file to disable these strict checks.  Alternatively,
078af19
you can pass `-z undefs` to ld (written as `-Wl,-z,undefs` on the gcc
078af19
command line).  The latter needs binutils 2.29.1-12.fc28 or later.
078af19
0d16217
# Individual compiler flags
0d16217
0d16217
Compiler flags end up in the environment variables `CFLAGS`,
0d16217
`CXXFLAGS`, `FFLAGS`, and `FCFLAGS`.
0d16217
0d16217
The general (architecture-independent) build flags are:
0d16217
0d16217
* `-O2`: Turn on various GCC optimizations.  See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-O2).
0d16217
  Optimization improves performance, the accuracy of warnings, and the
0d16217
  reach of toolchain-based hardening, but it makes debugging harder.
0d16217
* `-g`: Generate debugging information (DWARF).  In Fedora, this data
0d16217
  is separated into `-debuginfo` RPM packages whose installation is
0d16217
  optional, so debuging information does not increase the size of
0d16217
  installed binaries by default.
0d16217
* `-pipe`: Run compiler and assembler in parallel and do not use a
0d16217
  temporary file for the assembler input.  This can improve
0d16217
  compilation performance.  (This does not affect code generation.)
0d16217
* `-Wall`: Turn on various GCC warnings.
0d16217
  See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wall).
0d16217
* `-Werror=format-security`: Turn on format string warnings and treat
0d16217
  them as errors.
0d16217
  See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wformat-security).
0d16217
  This can occasionally result in compilation errors.  In this case,
0d16217
  the best option is to rewrite the source code so that only constant
0d16217
  format strings (string literals) are used.
0d16217
* `-Wp,-D_FORTIFY_SOURCE=2`: Source fortification activates various
0d16217
  hardening features in glibc:
0d16217
    * String functions such as `memcpy` attempt to detect buffer lengths
0d16217
      and terminate the process if a buffer overflow is detected.
0d16217
    * `printf` format strings may only contain the `%n` format specifier
0d16217
      if the format string resides in read-only memory.
0d16217
    * `open` and `openat` flags are checked for consistency with the
0d16217
      presence of a *mode* argument.
0d16217
    * Plus other minor hardening changes.
0d16217
  (These changes can occasionally break valid programs.)
0d16217
* `-fexceptions`: Provide exception unwinding support for C programs.
0d16217
  See the [`-fexceptions` option in the GCC
0d16217
  manual](https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fexceptions)
0d16217
  and the [`cleanup` variable
0d16217
  attribute](https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-cleanup-variable-attribute).
0d16217
  This also hardens cancellation handling in C programs because
0d16217
  it is not required to use an on-stack jump buffer to install
0d16217
  a cancellation handler with `pthread_cleanup_push`.  It also makes
0d16217
  it possible to unwind the stack (using C++ `throw` or Rust panics)
0d16217
  from C callback functions if a C library supports non-local exits
0d16217
  from them (e.g., via `longjmp`).
0d16217
* `-Wp,-D_GLIBCXX_ASSERTIONS`: Enable lightweight assertions in the
0d16217
  C++ standard library, such as bounds checking for the subscription
0d16217
  operator on vectors.  (This flag is added to both `CFLAGS` and
0d16217
  `CXXFLAGS`; C compilations will simply ignore it.)
0d16217
* `-fstack-protector-strong`: Instrument functions to detect
0d16217
  stack-based buffer overflows before jumping to the return address on
0d16217
  the stack.  The *strong* variant only performs the instrumentation
0d16217
  for functions whose stack frame contains addressable local
0d16217
  variables.  (If the address of a variable is never taken, it is not
0d16217
  possible that a buffer overflow is caused by incorrect pointer
0d16217
  arithmetic involving a pointer to that variable.)
0d16217
* `-grecord-gcc-switches`: Include select GCC command line switches in
0d16217
  the DWARF debugging information.  This is useful for detecting the
0d16217
  presence of certain build flags and general hardening coverage.
0d16217
0d16217
For hardened builds (which are enabled by default, see above for how
0d16217
to disable them), the flag
0d16217
`-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1` is added to the
0d16217
command line.  It adds the following flag to the command line:
0d16217
0d16217
*   `-fPIE`: Compile for a position-independent executable (PIE),
0d16217
    enabling full address space layout randomization (ASLR).  This is
0d16217
    similar to `-fPIC`, but avoids run-time indirections on certain
0d16217
    architectures, resulting in improved performance and slightly
0d16217
    smaller executables.  However, compared to position-dependent code
0d16217
    (the default generated by GCC), there is still a measurable
0d16217
    performance impact.
0d16217
0d16217
    If the command line also contains `-r` (producing a relocatable
0d16217
    object file), `-fpic` or `-fPIC`, this flag is automatically
0d16217
    dropped.  (`-fPIE` can only be used for code which is linked into
0d16217
    the main program.) Code which goes into static libraries should be
0d16217
    compiled with `-fPIE`, except when this code is expected to be
0d16217
    linked into DSOs, when `-fPIC` must be used.
0d16217
0d16217
    To be effective, `-fPIE` must be used with the `-pie` linker flag
0d16217
    when producing an executable, see below.
0d16217
0d16217
To support [binary watermarks for ELF
0d16217
objects](https://fedoraproject.org/wiki/Toolchain/Watermark) using
0d16217
annobin, the `-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1` flag is
0d16217
added by default.  This can be switched off by undefining the
0d16217
`%_annotated_build` RPM macro (see above).
0d16217
0d16217
### Architecture-specific compiler flags
0d16217
0d16217
These compiler flags are enabled for all builds (hardened/annotated or
0d16217
not), but their selection depends on the architecture:
0d16217
0d16217
*   `-fstack-clash-protection`: Turn on instrumentation to avoid
0d16217
    skipping the guard page in large stack frames.  (Without this flag,
0d16217
    vulnerabilities can result where the stack overlaps with the heap,
0d16217
    or thread stacks spill into other regions of memory.)  This flag is
0d16217
    fully ABI-compatible and has adds very little run-time overhead, but
5b96b31
    is only available on certain architectures (currently aarch64, i386,
72b1044
    ppc64, ppc64le, s390x, x86_64).
0d16217
*   `-m64` and `-m32`: Some GCC builds support both 32-bit and 64-bit in
0d16217
    the same compilation.  For such architectures, the RPM build process
0d16217
    explicitly selects the architecture variant by passing this compiler
0d16217
    flag.
0d16217
*   `-fasynchronous-unwind-tables`: Generate full unwind information
0d16217
    covering all program points.  This is required for support of
0d16217
    asynchronous cancellation and proper unwinding from signal
e43ce31
    handlers.  It also makes performance and debugging tools more
e43ce31
    useful because unwind information is available without having to
e43ce31
    install (and load) debugging ienformation.
e43ce31
    Asynchronous unwind tables are enabled for aarch64, i686, s390x,
72b1044
    and x86_64.  They are not needed on armhfp, ppc64 and ppc64le due
e43ce31
    to architectural differences in stack management.  On these
e43ce31
    architectures, `-fexceptions` (see above) still enables regular
e43ce31
    unwind tables (or they are enabled by default even without this
e43ce31
    option).
0d16217
0d16217
In addition, `redhat-rpm-config` re-selects the built-in default
0d16217
tuning in the `gcc` package.  These settings are:
0d16217
0d16217
*   **armhfp**: `-march=armv7-a -mfpu=vfpv3-d16  -mfloat-abi=hard`
0d16217
    selects an Arm subarchitecture based on the ARMv7-A architecture
75a53b7
    with 16 64-bit floating point registers.  `-mtune=cortex-8a` selects
75a53b7
    tuning for the Cortex-A8 implementation (while preserving compatibility
75a53b7
    with other ARMv7-A implementations).  `-mabi=aapcs-linux` switches to
75a53b7
    the AAPCS ABI for GNU/Linux.
0d16217
*   **i686**: `-march=i686` is used to select a minmum support CPU level
0d16217
    of i686 (corresponding to the Pentium Pro).
0d16217
*   **ppc64le**: `-mcpu=power8 -mtune=power8` selects a minimum supported
0d16217
    CPU level of POWER8 (the first CPU with ppc64le support) and tunes
0d16217
    for POWER8.
0d16217
*   **s390x**: `-march=zEC12 -mtune=z13` specifies a minimum supported CPU
0d16217
    level of zEC12, while optimizing for a subsequent CPU generation
0d16217
    (z13).
72b1044
*   **x86_64**: `-mtune=generic` selects tuning which is expected to
0d16217
     beneficial for a broad range of current CPUs.
0d16217
*   **ppc64** and **aarch64** do not have any architecture-specific tuning.
0d16217
0d16217
# Individual linker flags
0d16217
0d16217
Linker flags end up in the environment variable `LDFLAGS`.
0d16217
0d16217
The linker flags listed below are injected.  Note that they are
0d16217
prefixed with `-Wl` because it is expected that these flags are passed
0d16217
to the compiler driver `gcc`, and not directly to the link editor
0d16217
`ld`.
0d16217
0d16217
* `-z relro`: Activate the *read-only after relocation* feature.
0d16217
  Constant data and relocations are placed on separate pages, and the
0d16217
  dynamic linker is instructed to revoke write permissions after
0d16217
  dynamic linking.  Full protection of relocation data requires the
0d16217
  `-z now` flag (see below).
078af19
* `-z defs`: Refuse to link shared objects (DSOs) with undefined symbols.
078af19
  Such symbols lack symbol versioning information and can be bound to
078af19
  the wrong (compatibility) symbol version at run time, and not the
078af19
  actual (default) symbol version which would have been used if the
078af19
  symbol definition had been available and static link time.
0d16217
0d16217
For hardened builds, the
0d16217
`-specs=/usr/lib/rpm/redhat/redhat-hardened-ld` flag is added to the
0d16217
compiler driver command line.  (This can be disabled by undefining the
0d16217
`%_hardened_build` macro; see above) This activates the following
0d16217
linker flags:
0d16217
0d16217
* `-pie`: Produce a PIE binary.  This is only activated for the main
0d16217
  executable, and only if it is dynamically linked.  This requires
0d16217
  that all objects which are linked in the main executable have been
0d16217
  compiled with `-fPIE` or `-fPIC` (or `-fpie` or `-fpic`; see above).
0d16217
  By itself, `-pie` has only a slight performance impact because it
0d16217
  disables some link editor optimization, however the `-fPIE` compiler
0d16217
  flag has some overhead.
0d16217
* `-z now`: Disable lazy binding and turn on the `BIND_NOW` dynamic
0d16217
  linker feature.  Lazy binding involves an array of function pointers
0d16217
  which is writable at run time (which could be overwritten as part of
0d16217
  security exploits, redirecting execution).  Therefore, it is
0d16217
  preferable to turn of lazy binding, although it increases startup
0d16217
  time.