X-Git-Url: https://ruderich.org/simon/gitweb/?p=blhc%2Fblhc.git;a=blobdiff_plain;f=bin%2Fblhc;h=d2e5df761c09e45e5943cc7ba328cd8f34f3746f;hp=d53c7d7b849a01b62610263e851dde695f26dd41;hb=ea4a36f6673fe09075554d52d327149469d427a7;hpb=992cc016c9d07fab61701a75a0957dcfda83c77d diff --git a/bin/blhc b/bin/blhc index d53c7d7..d2e5df7 100755 --- a/bin/blhc +++ b/bin/blhc @@ -34,36 +34,41 @@ my $cc_regex = qr/(?:x86_64-linux-gnu-)?(?:(? '-Wl,-z,relro', @@ -198,20 +203,28 @@ sub is_non_verbose_build { # MAIN -# Additional hardening options. -my $pie = 0; -my $bindnow = 0; +# Hardening options. Not all architectures support all hardening options. +my $harden_format = 1; +my $harden_fortify = 1; +my $harden_stack = 1; +my $harden_relro = 1; +my $harden_bindnow = 0; +my $harden_pie = 0; # Parse command line arguments. -my $option_all = 0; my $option_help = 0; my $option_version = 0; +my $option_all = 0; +my $option_arch = undef; if (not Getopt::Long::GetOptions( 'help|h|?' => \$option_help, 'version' => \$option_version, - 'pie' => \$pie, - 'bindnow' => \$bindnow, + # Hardening options. + 'pie' => \$harden_pie, + 'bindnow' => \$harden_bindnow, 'all' => \$option_all, + # Misc. + 'arch' => \$option_arch, )) { require Pod::Usage; Pod::Usage::pod2usage(2); @@ -240,8 +253,8 @@ along with this program. If not, see . } if ($option_all) { - $pie = 1; - $bindnow = 1; + $harden_pie = 1; + $harden_bindnow = 1; } # Final exit code. @@ -258,6 +271,12 @@ while (my $line = <>) { $start = 1 if $line =~ /^dpkg-buildpackage:/; next if not $start; + # Detect architecture automatically unless overridden. + if (not $option_arch + and $line =~ /^dpkg-buildpackage: host architecture (.+)$/) { + $option_arch = $1; + } + # Ignore compiler warnings for now. next if $line =~ /$warning_regex/; @@ -305,18 +324,53 @@ if (scalar @input == 0) { exit $exit; } +# Option or auto detected. +if ($option_arch) { + # The following was partially copied from dpkg-dev 1.16.1.2 + # (/usr/share/perl5/Dpkg/Vendor/Debian.pm, add_hardening_flags()), + # copyright Raphaël Hertzog , Kees Cook + # , Canonical, Ltd. licensed under GPL version 2 or + # later. Keep it in sync. + + require Dpkg::Arch; + my ($abi, $os, $cpu) = Dpkg::Arch::debarch_to_debtriplet($option_arch); + + # Disable unsupported hardening options. + if ($cpu =~ /^(ia64|alpha|mips|mipsel|hppa)$/ or $option_arch eq 'arm') { + $harden_stack = 0; + } + if ($cpu =~ /^(ia64|hppa|avr32)$/) { + $harden_relro = 0; + $harden_bindnow = 0; + } +} + # Check if additional hardening options were used. Used to ensure they are # used for the complete build. foreach my $line (@input) { - $pie = 1 if any_flags_used($line, @cflags_pie, @ldflags_pie); - $bindnow = 1 if any_flags_used($line, @ldflags_bindnow); + $harden_pie = 1 if any_flags_used($line, @cflags_pie, @ldflags_pie); + $harden_bindnow = 1 if any_flags_used($line, @ldflags_bindnow); } -if ($pie) { +# Check the specified hardening options, same order as dpkg-buildflags. +if ($harden_pie) { @cflags = (@cflags, @cflags_pie); @ldflags = (@ldflags, @ldflags_pie); } -if ($bindnow) { +if ($harden_stack) { + @cflags = (@cflags, @cflags_stack); +} +if ($harden_fortify) { + @cflags = (@cflags, @cflags_fortify); + @cppflags = (@cppflags, @cppflags_fortify); +} +if ($harden_format) { + @cflags = (@cflags, @cflags_format); +} +if ($harden_relro) { + @ldflags = (@ldflags, @ldflags_relro); +} +if ($harden_bindnow) { @ldflags = (@ldflags, @ldflags_bindnow); } @@ -369,7 +423,7 @@ for (my $i = 0; $i < scalar @input; $i++) { if ($compiler and not all_flags_used($line, \@missing, @cflags) # Libraries linked with -fPIC don't have to (and can't) be linked # with -fPIE as well. It's no error if only PIE flags are missing. - and not pic_pie_conflict($line, $pie, \@missing, @cflags_pie)) { + and not pic_pie_conflict($line, $harden_pie, \@missing, @cflags_pie)) { error_flags('CFLAGS missing', \@missing, \%flag_renames, $line); $exit |= 1 << 3; } @@ -379,7 +433,7 @@ for (my $i = 0; $i < scalar @input; $i++) { } if ($linker and not all_flags_used($line, \@missing, @ldflags) # Same here, -fPIC conflicts with -fPIE. - and not pic_pie_conflict($line, $pie, \@missing, @ldflags_pie)) { + and not pic_pie_conflict($line, $harden_pie, \@missing, @ldflags_pie)) { error_flags('LDFLAGS missing', \@missing, \%flag_renames, $line); $exit |= 1 << 3; } @@ -405,6 +459,7 @@ B [--pie] [--bindnow] [--all] --pie force +pie check --bindnow force +bindbow check --all force +all (+pie, +bindnow) check + --arch set architecture (autodetected) =head1 DESCRIPTION @@ -436,6 +491,12 @@ Force check for all +bindnow hardening flags. By default it's auto detected. Force check for all +all (+pie, +bindnow) hardening flags. By default it's auto detected. +=item B<--arch> + +Set the specific architecture (e.g. amd64, armel, etc.), automatically +disables hardening flags not available on this architecture. Is detected +automatically if dpkg-buildpackage is used. + =back Auto detection only works if at least one command uses the required hardening