Browse Source

Dpkg::Vendor::Debian: Handle PIE enabled by default in gcc

Add support for compiler built-in features, so that we do not set
them when enabled and set negated flags when disabled.

We use gcc spec files to set these flags so that we avoid any conflict
with other incompatible flags that would make the build fail.

Closes: #835149
Based-on-patch-by: Bálint Réczey <balint@balintreczey.hu>
Guillem Jover 7 years ago
parent
commit
1852648603

+ 2 - 0
Makefile.am

@@ -20,6 +20,8 @@ ACLOCAL_AMFLAGS = -I m4
 
 
 dist_pkgdata_DATA = \
+	data/no-pie-compile.specs \
+	data/no-pie-link.specs \
 	data/cputable \
 	data/ostable \
 	data/abitable \

+ 2 - 0
data/no-pie-compile.specs

@@ -0,0 +1,2 @@
+*cc1_options:
++ %{!r:%{!fpie:%{!fPIE:%{!fpic:%{!fPIC:%{!fno-pic:-fno-PIE}}}}}}

+ 2 - 0
data/no-pie-link.specs

@@ -0,0 +1,2 @@
+*self_spec:
++ %{!shared:%{!r:-no-pie}}

+ 5 - 0
debian/changelog

@@ -69,6 +69,11 @@ dpkg (1.18.11) UNRELEASED; 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
+    Based on a patch by Bálint Réczey <balint@balintreczey.hu>.
   * Architecture support:
     - Add support for AIX operating system.
     - Add a version pseudo-field to the arch tables.

+ 1 - 0
debian/libdpkg-perl.install

@@ -1,3 +1,4 @@
+usr/share/dpkg/*.specs
 usr/share/locale/*/LC_MESSAGES/dpkg-dev.mo
 usr/share/man/man3/Dpkg*.3
 usr/share/perl5/Dpkg*

+ 14 - 5
man/dpkg-buildflags.man

@@ -147,7 +147,7 @@ For example:
 .IP
 .nf
   Feature: pie
-  Enabled: no
+  Enabled: yes
 
   Feature: stackprotector
   Enabled: yes
@@ -347,10 +347,19 @@ above). The option cannot become enabled if \fBrelro\fP is not enabled.
 .
 .TP
 .B pie
-This setting (disabled by default) 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. Position Independent
+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,
+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.
+
+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

+ 21 - 2
scripts/Dpkg/Vendor/Debian.pm

@@ -25,6 +25,7 @@ use warnings;
 
 our $VERSION = '0.01';
 
+use Dpkg;
 use Dpkg::Gettext;
 use Dpkg::ErrorHandling;
 use Dpkg::Control::Types;
@@ -280,7 +281,7 @@ sub _add_hardening_flags {
 
     # Default feature states.
     my %use_feature = (
-	pie => 0,
+	pie => 1,
 	stackprotector => 1,
 	stackprotectorstrong => 1,
 	fortify => 1,
@@ -288,10 +289,18 @@ sub _add_hardening_flags {
 	relro => 1,
 	bindnow => 0,
     );
+    my %builtin_feature = (
+        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.
+    if ($arch !~ /^(?:amd64|arm64|armel|armhf|i386|mips|mipsel|mips64el|ppc64el|s390x)$/) {
+        $builtin_feature{pie} = 0;
+    }
+
     # Mask features that are not available on certain architectures.
     if ($os !~ /^(?:linux|kfreebsd|knetbsd|hurd)$/ or
 	$cpu =~ /^(?:hppa|avr32)$/) {
@@ -330,7 +339,7 @@ sub _add_hardening_flags {
     }
 
     # PIE
-    if ($use_feature{pie}) {
+    if ($use_feature{pie} and not $builtin_feature{pie}) {
 	my $flag = '-fPIE';
 	$flags->append('CFLAGS', $flag);
 	$flags->append('OBJCFLAGS',  $flag);
@@ -340,6 +349,16 @@ sub _add_hardening_flags {
 	$flags->append('CXXFLAGS', $flag);
 	$flags->append('GCJFLAGS', $flag);
 	$flags->append('LDFLAGS', '-fPIE -pie');
+    } elsif (not $use_feature{pie} and $builtin_feature{pie}) {
+	my $flag = "-specs=$Dpkg::DATADIR/no-pie-compile.specs";
+	$flags->append('CFLAGS', $flag);
+	$flags->append('OBJCFLAGS',  $flag);
+	$flags->append('OBJCXXFLAGS', $flag);
+	$flags->append('FFLAGS', $flag);
+	$flags->append('FCFLAGS', $flag);
+	$flags->append('CXXFLAGS', $flag);
+	$flags->append('GCJFLAGS', $flag);
+	$flags->append('LDFLAGS', "-specs=$Dpkg::DATADIR/no-pie-link.specs");
     }
 
     # Stack protector