Document build flags
This commit is contained in:
parent
3bf139f646
commit
0d162176e9
228
buildflags.md
Normal file
228
buildflags.md
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
This document contains documentation of the individual compiler flags
|
||||||
|
and how to use them.
|
||||||
|
|
||||||
|
[TOC]
|
||||||
|
|
||||||
|
# Using RPM build flags
|
||||||
|
|
||||||
|
At present, the only supported way is to use the `%configure` macro to
|
||||||
|
obtain the full complement of flags, like this:
|
||||||
|
|
||||||
|
%configure
|
||||||
|
|
||||||
|
This will invoke the `./configure` with arguments (such as
|
||||||
|
`--prefix=/usr`) to adjust the paths to the packaging defaults.
|
||||||
|
|
||||||
|
As a side effect, this will set the environment variables `CFLAGS`,
|
||||||
|
`CXXFLAGS`, `FFLAGS`, `FCFLAGS`, and `LDFLAGS`, so they can be used by
|
||||||
|
makefiles and other build tools.
|
||||||
|
|
||||||
|
For some other build tools besides `autoconf`, separate mechanisms exist:
|
||||||
|
|
||||||
|
* CMake builds use the the `%cmake` macro from the `cmake-rpm-macros`
|
||||||
|
package.
|
||||||
|
|
||||||
|
Care must be taking not to compile the current selection of compiler
|
||||||
|
flags into any RPM package besides `redhat-rpm-config`, so that flag
|
||||||
|
changes are picked up automatically once `redhat-rpm-config` is
|
||||||
|
updated.
|
||||||
|
|
||||||
|
# Flag selection for the build type
|
||||||
|
|
||||||
|
The default flags are suitable for building applications.
|
||||||
|
|
||||||
|
For building shared objects, you must compile with `-fPIC` in
|
||||||
|
(`CFLAGS` or `CXXFLAGS`) and link with `-shared` (in `LDFLAGS`).
|
||||||
|
|
||||||
|
For other considerations involving shared objects, see:
|
||||||
|
|
||||||
|
* [Fedora Packaging Guidelines: Shared Libraries](https://fedoraproject.org/wiki/Packaging:Guidelines#Shared_Libraries)
|
||||||
|
|
||||||
|
# Customizing compiler flags
|
||||||
|
|
||||||
|
It is possible to set RPM macros to change some aspects of the
|
||||||
|
compiler flags. Changing these flags should be used as a last
|
||||||
|
recourse if other workarunds are not available.
|
||||||
|
|
||||||
|
### Disable hardened builds
|
||||||
|
|
||||||
|
%undefine _hardened_build
|
||||||
|
|
||||||
|
This turns off certain hardening features, as described in detail
|
||||||
|
below. The main difference is that executables will be
|
||||||
|
position-dependent (no full ASLR) and use lazy binding.
|
||||||
|
|
||||||
|
### Disable annotated builds/watermarking
|
||||||
|
|
||||||
|
%undefine _annotated_build
|
||||||
|
|
||||||
|
This turns off watermarking, making it impossible to do full hardening
|
||||||
|
coverage analysis for any binaries produced.
|
||||||
|
|
||||||
|
# Individual compiler flags
|
||||||
|
|
||||||
|
Compiler flags end up in the environment variables `CFLAGS`,
|
||||||
|
`CXXFLAGS`, `FFLAGS`, and `FCFLAGS`.
|
||||||
|
|
||||||
|
The general (architecture-independent) build flags are:
|
||||||
|
|
||||||
|
* `-O2`: Turn on various GCC optimizations. See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-O2).
|
||||||
|
Optimization improves performance, the accuracy of warnings, and the
|
||||||
|
reach of toolchain-based hardening, but it makes debugging harder.
|
||||||
|
* `-g`: Generate debugging information (DWARF). In Fedora, this data
|
||||||
|
is separated into `-debuginfo` RPM packages whose installation is
|
||||||
|
optional, so debuging information does not increase the size of
|
||||||
|
installed binaries by default.
|
||||||
|
* `-pipe`: Run compiler and assembler in parallel and do not use a
|
||||||
|
temporary file for the assembler input. This can improve
|
||||||
|
compilation performance. (This does not affect code generation.)
|
||||||
|
* `-Wall`: Turn on various GCC warnings.
|
||||||
|
See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wall).
|
||||||
|
* `-Werror=format-security`: Turn on format string warnings and treat
|
||||||
|
them as errors.
|
||||||
|
See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wformat-security).
|
||||||
|
This can occasionally result in compilation errors. In this case,
|
||||||
|
the best option is to rewrite the source code so that only constant
|
||||||
|
format strings (string literals) are used.
|
||||||
|
* `-Wp,-D_FORTIFY_SOURCE=2`: Source fortification activates various
|
||||||
|
hardening features in glibc:
|
||||||
|
* String functions such as `memcpy` attempt to detect buffer lengths
|
||||||
|
and terminate the process if a buffer overflow is detected.
|
||||||
|
* `printf` format strings may only contain the `%n` format specifier
|
||||||
|
if the format string resides in read-only memory.
|
||||||
|
* `open` and `openat` flags are checked for consistency with the
|
||||||
|
presence of a *mode* argument.
|
||||||
|
* Plus other minor hardening changes.
|
||||||
|
(These changes can occasionally break valid programs.)
|
||||||
|
* `-fexceptions`: Provide exception unwinding support for C programs.
|
||||||
|
See the [`-fexceptions` option in the GCC
|
||||||
|
manual](https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fexceptions)
|
||||||
|
and the [`cleanup` variable
|
||||||
|
attribute](https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-cleanup-variable-attribute).
|
||||||
|
This also hardens cancellation handling in C programs because
|
||||||
|
it is not required to use an on-stack jump buffer to install
|
||||||
|
a cancellation handler with `pthread_cleanup_push`. It also makes
|
||||||
|
it possible to unwind the stack (using C++ `throw` or Rust panics)
|
||||||
|
from C callback functions if a C library supports non-local exits
|
||||||
|
from them (e.g., via `longjmp`).
|
||||||
|
* `-Wp,-D_GLIBCXX_ASSERTIONS`: Enable lightweight assertions in the
|
||||||
|
C++ standard library, such as bounds checking for the subscription
|
||||||
|
operator on vectors. (This flag is added to both `CFLAGS` and
|
||||||
|
`CXXFLAGS`; C compilations will simply ignore it.)
|
||||||
|
* `-fstack-protector-strong`: Instrument functions to detect
|
||||||
|
stack-based buffer overflows before jumping to the return address on
|
||||||
|
the stack. The *strong* variant only performs the instrumentation
|
||||||
|
for functions whose stack frame contains addressable local
|
||||||
|
variables. (If the address of a variable is never taken, it is not
|
||||||
|
possible that a buffer overflow is caused by incorrect pointer
|
||||||
|
arithmetic involving a pointer to that variable.)
|
||||||
|
* `-grecord-gcc-switches`: Include select GCC command line switches in
|
||||||
|
the DWARF debugging information. This is useful for detecting the
|
||||||
|
presence of certain build flags and general hardening coverage.
|
||||||
|
|
||||||
|
For hardened builds (which are enabled by default, see above for how
|
||||||
|
to disable them), the flag
|
||||||
|
`-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1` is added to the
|
||||||
|
command line. It adds the following flag to the command line:
|
||||||
|
|
||||||
|
* `-fPIE`: Compile for a position-independent executable (PIE),
|
||||||
|
enabling full address space layout randomization (ASLR). This is
|
||||||
|
similar to `-fPIC`, but avoids run-time indirections on certain
|
||||||
|
architectures, resulting in improved performance and slightly
|
||||||
|
smaller executables. However, compared to position-dependent code
|
||||||
|
(the default generated by GCC), there is still a measurable
|
||||||
|
performance impact.
|
||||||
|
|
||||||
|
If the command line also contains `-r` (producing a relocatable
|
||||||
|
object file), `-fpic` or `-fPIC`, this flag is automatically
|
||||||
|
dropped. (`-fPIE` can only be used for code which is linked into
|
||||||
|
the main program.) Code which goes into static libraries should be
|
||||||
|
compiled with `-fPIE`, except when this code is expected to be
|
||||||
|
linked into DSOs, when `-fPIC` must be used.
|
||||||
|
|
||||||
|
To be effective, `-fPIE` must be used with the `-pie` linker flag
|
||||||
|
when producing an executable, see below.
|
||||||
|
|
||||||
|
To support [binary watermarks for ELF
|
||||||
|
objects](https://fedoraproject.org/wiki/Toolchain/Watermark) using
|
||||||
|
annobin, the `-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1` flag is
|
||||||
|
added by default. This can be switched off by undefining the
|
||||||
|
`%_annotated_build` RPM macro (see above).
|
||||||
|
|
||||||
|
### Architecture-specific compiler flags
|
||||||
|
|
||||||
|
These compiler flags are enabled for all builds (hardened/annotated or
|
||||||
|
not), but their selection depends on the architecture:
|
||||||
|
|
||||||
|
* `-fstack-clash-protection`: Turn on instrumentation to avoid
|
||||||
|
skipping the guard page in large stack frames. (Without this flag,
|
||||||
|
vulnerabilities can result where the stack overlaps with the heap,
|
||||||
|
or thread stacks spill into other regions of memory.) This flag is
|
||||||
|
fully ABI-compatible and has adds very little run-time overhead, but
|
||||||
|
is only on certain architectures (currently aarch64, i386, ppc64,
|
||||||
|
ppc64le, s390x, x86-64).
|
||||||
|
* `-m64` and `-m32`: Some GCC builds support both 32-bit and 64-bit in
|
||||||
|
the same compilation. For such architectures, the RPM build process
|
||||||
|
explicitly selects the architecture variant by passing this compiler
|
||||||
|
flag.
|
||||||
|
* `-fasynchronous-unwind-tables`: Generate full unwind information
|
||||||
|
covering all program points. This is required for support of
|
||||||
|
asynchronous cancellation and proper unwinding from signal
|
||||||
|
handlers. It also makes performance and debugging tools more useful
|
||||||
|
because unwind information is available without having to install
|
||||||
|
(and load) debugging information.
|
||||||
|
This flag is enabled explictly for i686 (and derived architectures),
|
||||||
|
and implicity for x86-64.
|
||||||
|
|
||||||
|
In addition, `redhat-rpm-config` re-selects the built-in default
|
||||||
|
tuning in the `gcc` package. These settings are:
|
||||||
|
|
||||||
|
* **armhfp**: `-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard`
|
||||||
|
selects an Arm subarchitecture based on the ARMv7-A architecture
|
||||||
|
with 16 64-bit floating point registers.
|
||||||
|
* **i686**: `-march=i686` is used to select a minmum support CPU level
|
||||||
|
of i686 (corresponding to the Pentium Pro).
|
||||||
|
* **ppc64le**: `-mcpu=power8 -mtune=power8` selects a minimum supported
|
||||||
|
CPU level of POWER8 (the first CPU with ppc64le support) and tunes
|
||||||
|
for POWER8.
|
||||||
|
* **s390x**: `-march=zEC12 -mtune=z13` specifies a minimum supported CPU
|
||||||
|
level of zEC12, while optimizing for a subsequent CPU generation
|
||||||
|
(z13).
|
||||||
|
* **x86-64**: `-mtune=generic` selects tuning which is expected to
|
||||||
|
beneficial for a broad range of current CPUs.
|
||||||
|
* **ppc64** and **aarch64** do not have any architecture-specific tuning.
|
||||||
|
|
||||||
|
# Individual linker flags
|
||||||
|
|
||||||
|
Linker flags end up in the environment variable `LDFLAGS`.
|
||||||
|
|
||||||
|
The linker flags listed below are injected. Note that they are
|
||||||
|
prefixed with `-Wl` because it is expected that these flags are passed
|
||||||
|
to the compiler driver `gcc`, and not directly to the link editor
|
||||||
|
`ld`.
|
||||||
|
|
||||||
|
* `-z relro`: Activate the *read-only after relocation* feature.
|
||||||
|
Constant data and relocations are placed on separate pages, and the
|
||||||
|
dynamic linker is instructed to revoke write permissions after
|
||||||
|
dynamic linking. Full protection of relocation data requires the
|
||||||
|
`-z now` flag (see below).
|
||||||
|
|
||||||
|
For hardened builds, the
|
||||||
|
`-specs=/usr/lib/rpm/redhat/redhat-hardened-ld` flag is added to the
|
||||||
|
compiler driver command line. (This can be disabled by undefining the
|
||||||
|
`%_hardened_build` macro; see above) This activates the following
|
||||||
|
linker flags:
|
||||||
|
|
||||||
|
* `-pie`: Produce a PIE binary. This is only activated for the main
|
||||||
|
executable, and only if it is dynamically linked. This requires
|
||||||
|
that all objects which are linked in the main executable have been
|
||||||
|
compiled with `-fPIE` or `-fPIC` (or `-fpie` or `-fpic`; see above).
|
||||||
|
By itself, `-pie` has only a slight performance impact because it
|
||||||
|
disables some link editor optimization, however the `-fPIE` compiler
|
||||||
|
flag has some overhead.
|
||||||
|
* `-z now`: Disable lazy binding and turn on the `BIND_NOW` dynamic
|
||||||
|
linker feature. Lazy binding involves an array of function pointers
|
||||||
|
which is writable at run time (which could be overwritten as part of
|
||||||
|
security exploits, redirecting execution). Therefore, it is
|
||||||
|
preferable to turn of lazy binding, although it increases startup
|
||||||
|
time.
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
Summary: Red Hat specific rpm configuration files
|
Summary: Red Hat specific rpm configuration files
|
||||||
Name: redhat-rpm-config
|
Name: redhat-rpm-config
|
||||||
Version: 79
|
Version: 80
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
# No version specified.
|
# No version specified.
|
||||||
License: GPL+
|
License: GPL+
|
||||||
@ -64,6 +64,9 @@ Source600: kmod.attr
|
|||||||
Source601: kmod.prov
|
Source601: kmod.prov
|
||||||
Source602: libsymlink.attr
|
Source602: libsymlink.attr
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
Source900: buildflags.md
|
||||||
|
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
BuildRequires: perl-generators
|
BuildRequires: perl-generators
|
||||||
Requires: coreutils
|
Requires: coreutils
|
||||||
@ -140,6 +143,7 @@ install -p -m 755 -t %{buildroot}%{_rpmconfigdir} kmod.prov
|
|||||||
%{_rpmconfigdir}/macros.d/macros.dwz
|
%{_rpmconfigdir}/macros.d/macros.dwz
|
||||||
%{_rpmconfigdir}/macros.d/macros.forge
|
%{_rpmconfigdir}/macros.d/macros.forge
|
||||||
%{_rpmconfigdir}/macros.d/macros.vpath
|
%{_rpmconfigdir}/macros.d/macros.vpath
|
||||||
|
%doc buildflags.md
|
||||||
|
|
||||||
%files -n kernel-rpm-macros
|
%files -n kernel-rpm-macros
|
||||||
%dir %{rrcdir}/find-provides.d
|
%dir %{rrcdir}/find-provides.d
|
||||||
@ -153,6 +157,9 @@ install -p -m 755 -t %{buildroot}%{_rpmconfigdir} kmod.prov
|
|||||||
%{_rpmconfigdir}/macros.d/macros.kmp
|
%{_rpmconfigdir}/macros.d/macros.kmp
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Jan 22 2018 Florian Weimer <fweimer@redhat.com> - 80-1
|
||||||
|
- Document build flags
|
||||||
|
|
||||||
* Fri Jan 19 2018 Panu Matilainen <pmatilai@redhat.com> - 79-1
|
* Fri Jan 19 2018 Panu Matilainen <pmatilai@redhat.com> - 79-1
|
||||||
- Document how to disable hardened and annotated build (#1211296)
|
- Document how to disable hardened and annotated build (#1211296)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user