]> ruderich.org/simon Gitweb - blhc/blhc.git/blobdiff - bin/blhc
Sync architecture specific hardening support with dpkg 1.17.1.
[blhc/blhc.git] / bin / blhc
index 783ae73f27b66eb68df2fbc3c8e9c1635ebbfd2d..b5177bdda7b88e6a452c57c93f091318c5d4301d 100755 (executable)
--- a/bin/blhc
+++ b/bin/blhc
@@ -176,7 +176,8 @@ my $file_extension_regex = qr/
                     # terminated with "\n".
     /x;
 
-# Expected (hardening) flags. All flags are used as regexps.
+# Expected (hardening) flags. All flags are used as regexps (and compiled to
+# real regexps below for better execution speed).
 my @def_cflags = (
     '-g',
     '-O(?:2|3)',
@@ -475,6 +476,7 @@ sub is_non_verbose_build {
     return 1;
 }
 
+# Remove @flags from $flag_refs_ref, and $flag_renames_ref.
 sub remove_flags {
     my ($flag_refs_ref, $flag_renames_ref, @flags) = @_;
 
@@ -492,35 +494,37 @@ sub remove_flags {
     return;
 }
 
+# Modifies $flag_renames_ref hash.
 sub compile_flag_regexp {
     my ($flag_renames_ref, @flags) = @_;
 
     my @result = ();
     foreach my $flag (@flags) {
+        # Compile flag regexp for faster execution.
+        my $regex = qr/\s$flag(?:\s|\\)/;
+
         # Store flag name in replacement string for correct flags in messages
         # with qr//ed flag regexps.
-        $flag_renames_ref->{qr/\s$flag(?:\s|\\)/}
+        $flag_renames_ref->{$regex}
             = (exists $flag_renames_ref->{$flag})
                 ? $flag_renames_ref->{$flag}
                 : $flag;
 
-        # Compile flag regexp for faster execution.
-        push @result, qr/\s$flag(?:\s|\\)/;
+        push @result, $regex;
     }
     return @result;
 }
 
+# Does any extension in @extensions exist in %{$extensions_ref}?
 sub extension_found {
     my ($extensions_ref, @extensions) = @_;
 
-    my $found = 0;
     foreach my $extension (@extensions) {
         if (exists $extensions_ref->{$extension}) {
-            $found = 1;
-            last;
+            return 1;
         }
     }
-    return $found;
+    return 0;
 }
 
 
@@ -566,7 +570,8 @@ if ($option_help) {
     Pod::Usage::pod2usage(1);
 }
 if ($option_version) {
-    print "blhc $VERSION  Copyright (C) 2012-2013  Simon Ruderich
+    print <<"EOF";
+blhc $VERSION  Copyright (C) 2012-2013  Simon Ruderich
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -580,7 +585,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
-";
+EOF
     exit 0;
 }
 
@@ -852,14 +857,18 @@ foreach my $file (@ARGV) {
             next if $line =~ /^\s*(?:Host\s+)?(?:C(?:\+\+)?\s+)?
                                 [Cc]ompiler[\s.]*:?\s+
                                 /x;
-            next if $line =~ /^\s*(?:- )?(?:HOST_)?(?:CC|CXX)\s*=\s*$cc_regex_full\s*$/o;
+            next if $line =~ m{^\s*(?:-\s)?(?:HOST_)?(?:CC|CXX)
+                                \s*=\s*$cc_regex_full
+                                # optional compiler options, don't allow
+                                # "everything" here to prevent false negatives
+                                \s*(?:\s-\S+)*\s*$}xo;
             # `moc-qt4`/`moc-qt5` contain '-I.../linux-g++' in their command
             # line (or similar for other architectures) which gets recognized
             # as a compiler line, but `moc-qt*` is only a preprocessor for Qt
             # C++ files. No hardening flags are relevant during this step,
             # thus ignore `moc-qt*` lines. The resulting files will be
             # compiled in a separate step (and therefore checked).
-            next if $line =~ m{^\S+/bin/moc-qt[45]
+            next if $line =~ m{^\S+/bin/moc(?:-qt[45])?
                                \s.+\s
                                -I\S+/mkspecs/[a-z]+-g\++(?:-64)?
                                \s}x;
@@ -911,7 +920,7 @@ foreach my $file (@ARGV) {
 
     # Option or auto detected.
     if ($arch) {
-        # The following was partially copied from dpkg-dev 1.16.4.3
+        # The following was partially copied from dpkg-dev 1.17.1
         # (/usr/share/perl5/Dpkg/Vendor/Debian.pm, add_hardening_flags()),
         # copyright RaphaĆ«l Hertzog <hertzog@debian.org>, Kees Cook
         # <kees@debian.org>, Canonical, Ltd. licensed under GPL version 2 or
@@ -921,7 +930,12 @@ foreach my $file (@ARGV) {
         my ($abi, $os, $cpu) = Dpkg::Arch::debarch_to_debtriplet($arch);
 
         # Disable unsupported hardening options.
-        if ($cpu =~ /^(?:ia64|alpha|mips|mipsel|hppa)$/ or $arch eq 'arm') {
+        if ($os !~ /^(?:linux|knetbsd|hurd)$/ or
+                $cpu =~ /^(?:hppa|mips|mipsel|avr32)$/) {
+            $harden_pie = 0;
+        }
+        if ($cpu =~ /^(?:ia64|alpha|mips|mipsel|hppa|arm64)$/
+                or $arch eq 'arm') {
             $harden_stack = 0;
         }
         if ($cpu =~ /^(?:ia64|hppa|avr32)$/) {
@@ -1019,7 +1033,8 @@ LINE:
             }
             next;
         }
-        # Even if it's a verbose build, we might have to skip this line.
+        # Even if it's a verbose build, we might have to skip this line (see
+        # is_non_verbose_build()).
         next if $skip;
 
         # Remove everything until and including the compiler command. Makes