diff options
| author | Guillem Jover <guillem@debian.org> | 2016-08-10 20:51:11 (GMT) |
|---|---|---|
| committer | Guillem Jover <guillem@debian.org> | 2016-11-07 02:25:46 (GMT) |
| commit | cf7f30aeba89f5bafe5046b7666985b661eaf217 (patch) | |
| tree | f5b6a7d9e5de8bc0e73a7f678cdb2f7590f5ab32 | |
| parent | f3b7b1c9683b68066c11b32a0a839293d4a32636 (diff) | |
Dpkg::Vendor::Debian: Improve PIE flags support
Fix changelog for dpkg 1.18.11 to mention PIE got enabled by default for
all architectures, not just the ones where gcc does that itself.
When emitting PIE flags on architectures where gcc does not inject those
itself, do it via a specs file too, so that maintainers can use them
unconditionally regardless of the object being compiled or linked.
When injecting -no-pie for linking via gcc specs also inject -fno-PIE.
Update the documentation to make the current situation more clear.
| -rw-r--r-- | Makefile.am | 2 | ||||
| -rw-r--r-- | data/no-pie-link.specs | 2 | ||||
| -rw-r--r-- | data/pie-compile.specs | 2 | ||||
| -rw-r--r-- | data/pie-link.specs | 2 | ||||
| -rw-r--r-- | debian/changelog | 20 | ||||
| -rw-r--r-- | man/dpkg-buildflags.man | 31 | ||||
| -rw-r--r-- | scripts/Dpkg/Vendor/Debian.pm | 12 |
7 files changed, 47 insertions, 24 deletions
diff --git a/Makefile.am b/Makefile.am index 27e7eae..0da52cb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,6 +20,8 @@ ACLOCAL_AMFLAGS = -I m4 dist_pkgdata_DATA = \ + data/pie-compile.specs \ + data/pie-link.specs \ data/no-pie-compile.specs \ data/no-pie-link.specs \ data/cputable \ diff --git a/data/no-pie-link.specs b/data/no-pie-link.specs index 07df312..15243a0 100644 --- a/data/no-pie-link.specs +++ b/data/no-pie-link.specs @@ -1,2 +1,2 @@ *self_spec: -+ %{!shared:%{!r:-no-pie}} ++ %{!shared:%{!r:-fno-PIE -no-pie}} diff --git a/data/pie-compile.specs b/data/pie-compile.specs new file mode 100644 index 0000000..fc54bcb --- /dev/null +++ b/data/pie-compile.specs @@ -0,0 +1,2 @@ +*cc1_options: ++ %{!r:%{!fpie:%{!fPIE:%{!fpic:%{!fPIC:%{!fno-pic:-fPIE}}}}}} diff --git a/data/pie-link.specs b/data/pie-link.specs new file mode 100644 index 0000000..a5e0fe4 --- /dev/null +++ b/data/pie-link.specs @@ -0,0 +1,2 @@ +*self_spec: ++ %{!shared:%{!r:-fPIE -pie}} diff --git a/debian/changelog b/debian/changelog index 1b0b686..2e97633 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,16 @@ dpkg (1.18.13) UNRELEASED; urgency=medium + * Improve PIE flags support: + - Retroactively document in the changelog that PIE is enabled by default + on all supported architectures regardless of gcc doing so itself on a + subset of them. + - When emitting PIE flags on architectures where gcc does not inject + those itself, do it via a specs file too, so that maintainers can + use them unconditionally regardless of the object being compiled + or linked. + - When injecting -no-pie for linking via the gcc specs file also + inject -fno-PIE. + - Update the documentation. * Perl modules: - Do not try to load non-files in Dpkg::Dist::Files load_dir method. Fixes test failures on non-Linux architectures. Closes: #843436 @@ -97,10 +108,11 @@ dpkg (1.18.11) unstable; urgency=medium * Enable dpkg-buildpackage -Jauto by default. Closes: #842845 * Fix dpkg to not fail when removing non-existent backup files on read-only filesystems. Closes: #838877 - * Handle PIE enabled by default in gcc. On achitectures where gcc enables - them by default, stop setting -fPIE and -pie, and set -fno-PIE and - -no-pie when disabling «pie» via gcc specs files, so that we do not - emit them on situations where it would be inappropriate. Closes: #835149 + * Enable PIE on all supported architectures and handle PIE enabled by + default in gcc. On achitectures where gcc enables them by default, + stop setting -fPIE and -pie, and set -fno-PIE and -no-pie when disabling + «pie» via gcc specs files, so that we do not emit them on situations + where it would be inappropriate. Closes: #835149 Based on a patch by Bálint Réczey <balint@balintreczey.hu>. * Architecture support: - Add support for AIX operating system. diff --git a/man/dpkg-buildflags.man b/man/dpkg-buildflags.man index a070cef..946f6d1 100644 --- a/man/dpkg-buildflags.man +++ b/man/dpkg-buildflags.man @@ -347,30 +347,32 @@ above). The option cannot become enabled if \fBrelro\fP is not enabled. . .TP .B pie -This setting (enabled and injected by default by gcc on the amd64, -arm64, armel, armhf, i386, mips, mipsel, mips64el, ppc64el and s390x -architectures, since dpkg 1.18.11) adds the required options if needed -to enable or disable PIE. When enabled and injected by gcc, +This setting (enabled by default since dpkg 1.18.11, and injected by default +by gcc on the amd64, arm64, armel, armhf, i386, mips, mipsel, mips64el, +ppc64el and s390x Debian architectures) adds the required options if +needed to enable or disable PIE. When enabled and injected by gcc, adds nothing. When enabled and not injected by gcc, adds \fB\-fPIE\fP to \fBCFLAGS\fP, \fBCXXFLAGS\fP, \fBOBJCFLAGS\fP, \fBOBJCXXFLAGS\fP, \fBGCJFLAGS\fP, \fBFFLAGS\fP and \fBFCFLAGS\fP, and \fB\-fPIE \-pie\fP to \fBLDFLAGS\fP. When disabled and injected by gcc, adds \fB\-fno\-PIE\fP to \fBCFLAGS\fP, \fBCXXFLAGS\fP, \fBOBJCFLAGS\fP, \fBOBJCXXFLAGS\fP, \fBGCJFLAGS\fP, \fBFFLAGS\fP and \fBFCFLAGS\fP, and -\fB\-no\-pie\fP to \fBLDFLAGS\fP. +\fB\-fno\-PIE \-no\-pie\fP to \fBLDFLAGS\fP. Position Independent Executable are needed to take advantage of Address Space Layout Randomization, supported by some kernel versions. While ASLR can already be enforced for data areas in the stack and heap (brk and mmap), the code areas must be compiled as position-independent. Shared libraries already -do this (\-fPIC), so they gain ASLR automatically, but binary .text +do this (\fB\-fPIC\fP), so they gain ASLR automatically, but binary .text regions need to be build PIE to gain ASLR. When this happens, ROP (Return Oriented Programming) attacks are much harder since there are no static locations to bounce off of during a memory corruption attack. -This is not compatible with \fB\-fPIC\fP so care must be taken when -building shared objects. +PIE is not compatible with \fB\-fPIC\fP, so in general care must be taken +when building shared objects. But because the PIE flags emitted get injected +via gcc specs files, it should always be safe to unconditionally set them +regardless of the object type being compiled or linked. Static libraries can be used by programs or other shared libraries. Depending on the flags used to compile all the objects within a static @@ -382,22 +384,25 @@ none Cannot be linked into a PIE program, nor a shared library. .TP .B \-fPIE -Can be linked into any program, but not a shared library. +Can be linked into any program, but not a shared library (recommended). .TP .B \-fPIC Can be linked into any program and shared library. .RE .IP -Unconditionally passing \fB\-fPIE\fP, \fB\-fpie\fP or \fB\-pie\fP to a -build-system using libtool is safe as these flags will get stripped when -building shared libraries. +If there is a need to set these flags manually, bypassing the gcc specs +injection, there are several things to take into account. Unconditionally +and explicitly passing \fB\-fPIE\fP, \fB\-fpie\fP or \fB\-pie\fP to a +build-system using libtool is safe as these flags will get stripped +when building shared libraries. Otherwise on projects that build both programs and shared libraries you might need to make sure that when building the shared libraries \fB\-fPIC\fP is always passed last (so that it overrides any previous \fB\-PIE\fP) to compilation flags such as \fBCFLAGS\fP, and \fB\-shared\fP is passed last (so that it overrides any previous \fB\-pie\fP) to linking flags such as -\fBLDFLAGS\fP. +\fBLDFLAGS\fP. \fBNote:\fP This should not be needed with the default +gcc specs machinery. .IP Additionally, since PIE is implemented via a general register, some diff --git a/scripts/Dpkg/Vendor/Debian.pm b/scripts/Dpkg/Vendor/Debian.pm index 043b31b..e4ba2e0 100644 --- a/scripts/Dpkg/Vendor/Debian.pm +++ b/scripts/Dpkg/Vendor/Debian.pm @@ -293,14 +293,14 @@ sub _add_hardening_flags { pie => 1, ); - # Adjust features based on user or maintainer's desires. - $self->_parse_feature_area('hardening', \%use_feature); - - # Mask features that are not enabled by default in the compiler. + # Mask builtin features that are not enabled by default in the compiler. if ($arch !~ /^(?:amd64|arm64|armel|armhf|i386|mips|mipsel|mips64el|ppc64el|s390x)$/) { $builtin_feature{pie} = 0; } + # Adjust features based on user or maintainer's desires. + $self->_parse_feature_area('hardening', \%use_feature); + # Mask features that are not available on certain architectures. if ($os !~ /^(?:linux|kfreebsd|knetbsd|hurd)$/ or $cpu =~ /^(?:hppa|avr32)$/) { @@ -340,7 +340,7 @@ sub _add_hardening_flags { # PIE if ($use_feature{pie} and not $builtin_feature{pie}) { - my $flag = '-fPIE'; + my $flag = "-specs=$Dpkg::DATADIR/pie-compile.specs"; $flags->append('CFLAGS', $flag); $flags->append('OBJCFLAGS', $flag); $flags->append('OBJCXXFLAGS', $flag); @@ -348,7 +348,7 @@ sub _add_hardening_flags { $flags->append('FCFLAGS', $flag); $flags->append('CXXFLAGS', $flag); $flags->append('GCJFLAGS', $flag); - $flags->append('LDFLAGS', '-fPIE -pie'); + $flags->append('LDFLAGS', "-specs=$Dpkg::DATADIR/pie-link.specs"); } elsif (not $use_feature{pie} and $builtin_feature{pie}) { my $flag = "-specs=$Dpkg::DATADIR/no-pie-compile.specs"; $flags->append('CFLAGS', $flag); |
