[arch-projects] [devtools] [PATCH] enforce hardening flags and use PIE on x86_64
PIE is required for full address space layout optimization (ASLR) and there is little to no benefit from ASLR without it since global ELF tables (GOT/PLT) and application code are at known locations. A wrapper script is required in order to pass the correct flags for executables without changing the flags for libraries. It adds `-pie` when linking (no `-c` switch) if `-static` or `-shared` are not passed, and `-fPIE` whenever `-fPIC` is not already there. This technique comes from the Debian hardening wrappers. Position independent code is expensive on i686, so it's only enabled by default on x86_64 where the cost is negligible. It can be enabled on a package-by-package basis on i686. The same cost already exists for any code in a dynamic library. The hardening-wrapper package also enforces the chosen hardening flags even when build systems aren't using CFLAGS / CXXFLAGS / LDFLAGS from the environment. It would need to be moved from [community] to [core]. --- archbuild.in | 5 +++-- makechrootpkg.in | 12 +++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/archbuild.in b/archbuild.in index ae2f511..419ae5b 100644 --- a/archbuild.in +++ b/archbuild.in @@ -2,7 +2,7 @@ m4_include(lib/common.sh) -base_packages=(base-devel) +base_packages=(base-devel hardening-wrapper) makechrootpkg_args=(-c -n) cmd="${0##*/}" @@ -67,11 +67,12 @@ if ${clean_first} || [[ ! -d "${chroots}/${repo}-${arch}" ]]; then "${base_packages[@]}" || abort else lock 9 "${chroots}/${repo}-${arch}/root.lock" "Locking clean chroot" + # upgrade and install any new packages from base_packages arch-nspawn \ -C "@pkgdatadir@/pacman-${repo}.conf" \ -M "@pkgdatadir@/makepkg-${arch}.conf" \ "${chroots}/${repo}-${arch}/root" \ - pacman -Syu --noconfirm || abort + pacman -Syu --noconfirm --needed "${base_packages[@]}" || abort fi msg "Building in chroot for [${repo}] (${arch})..." diff --git a/makechrootpkg.in b/makechrootpkg.in index 97c7780..ad804fc 100644 --- a/makechrootpkg.in +++ b/makechrootpkg.in @@ -320,7 +320,17 @@ _chrootbuild() { exit 1 fi - sudo -u nobody makepkg $makepkg_args || exit 1 + # enforced compiler hardening flags (can be overriden in a PKGBUILD) + export HARDENING_BINDNOW=0 HARDENING_FORTIFY=2 HARDENING_RELRO=1 + export HARDENING_STACK_CHECK=0 HARDENING_STACK_PROTECTOR=2 + . /etc/makepkg.conf + if [[ $CARCH = i686 ]]; then + export HARDENING_PIE=0 + else + export HARDENING_PIE=1 + fi + + sudo -E -u nobody makepkg $makepkg_args || exit 1 if $run_namcap; then pacman -S --needed --noconfirm namcap -- 2.0.2
Am 23.07.2014 22:17, schrieb Daniel Micay:
PIE is required for full address space layout optimization (ASLR) and there is little to no benefit from ASLR without it since global ELF tables (GOT/PLT) and application code are at known locations.
A wrapper script is required in order to pass the correct flags for executables without changing the flags for libraries. It adds `-pie` when linking (no `-c` switch) if `-static` or `-shared` are not passed, and `-fPIE` whenever `-fPIC` is not already there. This technique comes from the Debian hardening wrappers.
Position independent code is expensive on i686, so it's only enabled by default on x86_64 where the cost is negligible. It can be enabled on a package-by-package basis on i686. The same cost already exists for any code in a dynamic library.
The hardening-wrapper package also enforces the chosen hardening flags even when build systems aren't using CFLAGS / CXXFLAGS / LDFLAGS from the environment. It would need to be moved from [community] to [core].
Why should this be in devtools? The build settings are configured in makepkg and we should not split this into two places.
On 23/07/14 05:21 PM, Thomas Bächler wrote:
Am 23.07.2014 22:17, schrieb Daniel Micay:
PIE is required for full address space layout optimization (ASLR) and there is little to no benefit from ASLR without it since global ELF tables (GOT/PLT) and application code are at known locations.
A wrapper script is required in order to pass the correct flags for executables without changing the flags for libraries. It adds `-pie` when linking (no `-c` switch) if `-static` or `-shared` are not passed, and `-fPIE` whenever `-fPIC` is not already there. This technique comes from the Debian hardening wrappers.
Position independent code is expensive on i686, so it's only enabled by default on x86_64 where the cost is negligible. It can be enabled on a package-by-package basis on i686. The same cost already exists for any code in a dynamic library.
The hardening-wrapper package also enforces the chosen hardening flags even when build systems aren't using CFLAGS / CXXFLAGS / LDFLAGS from the environment. It would need to be moved from [community] to [core].
Why should this be in devtools? The build settings are configured in makepkg and we should not split this into two places.
Well, my earlier patch did that, but PIE is dealt with using distribution-specific machinery so it didn't really belong there: https://mailman.archlinux.org/pipermail/pacman-dev/2014-July/019202.html An alternative would be having makepkg (pacman) depend on the hardening-wrapper package and setting the appropriate HARDENING_* variables in makepkg.conf. HARDENED_PIE needs to vary based on CARCH to avoid a performance hit on i686, so it can't really be dealt with using defaults inside the wrapper.
On 23/07/14 05:21 PM, Thomas Bächler wrote:
Am 23.07.2014 22:17, schrieb Daniel Micay:
PIE is required for full address space layout optimization (ASLR) and there is little to no benefit from ASLR without it since global ELF tables (GOT/PLT) and application code are at known locations.
A wrapper script is required in order to pass the correct flags for executables without changing the flags for libraries. It adds `-pie` when linking (no `-c` switch) if `-static` or `-shared` are not passed, and `-fPIE` whenever `-fPIC` is not already there. This technique comes from the Debian hardening wrappers.
Position independent code is expensive on i686, so it's only enabled by default on x86_64 where the cost is negligible. It can be enabled on a package-by-package basis on i686. The same cost already exists for any code in a dynamic library.
The hardening-wrapper package also enforces the chosen hardening flags even when build systems aren't using CFLAGS / CXXFLAGS / LDFLAGS from the environment. It would need to be moved from [community] to [core].
Why should this be in devtools? The build settings are configured in makepkg and we should not split this into two places.
I went ahead and altered the hardening-wrapper script so that it doesn't require any devtools / makepkg modifications. It does add a new /etc/hardening-wrapper.conf configuration file though... I don't really want to encode the difference between i686 / x86_64 into the script itself by installing a separate one on both architectures.
participants (2)
-
Daniel Micay
-
Thomas Bächler