X-Git-Url: https://ruderich.org/simon/gitweb/?a=blobdiff_plain;f=bin%2Fblhc;h=daa0298e6d7a294ae9b1ed69860260bcd4db1389;hb=fbc6886e558ccf337cf7dd1eaa9a647c44ac2118;hp=f7988b5d1e5914a9b414ab504908cf506a19c67a;hpb=516e39a71f9a8f6e0d01fd13c40e4db0557de8df;p=blhc%2Fblhc.git diff --git a/bin/blhc b/bin/blhc index f7988b5..daa0298 100755 --- a/bin/blhc +++ b/bin/blhc @@ -38,15 +38,19 @@ my $cc_regex = qr/(?:[a-z0-9_]+-(?:linux-|kfreebsd-)?gnu(?:eabi|eabihf)?-)? my $warning_regex = qr/^(.+?):([0-9]+):[0-9]+: warning: (.+?) \[(.+?)\]$/; # Regex for source files which require preprocessing. +my $source_preprocess_compile_cpp_regex = qr/ + # C++ + cc | cp | cxx | cpp | CPP | c\+\+ | C + # Objective-C++ + | mm | M + /x; my $source_preprocess_compile_regex = qr/ # C c # Objective-C | m - # C++ - | cc | cp | cxx | cpp | CPP | c\+\+ | C - # Objective-C++ - | mm | M + # (Objective-)C++ + | $source_preprocess_compile_cpp_regex # Fortran | F | FOR | fpp | FPP | FTN | F90 | F95 | F03 | F08 /x; @@ -59,15 +63,19 @@ my $source_preprocess_regex = qr/ | $source_preprocess_no_compile_regex /x; # Regex for source files which don't require preprocessing. +my $source_no_preprocess_compile_cpp_regex = qr/ + # C++ + ii + # Objective-C++ + | mii + /x; my $source_no_preprocess_compile_regex = qr/ # C i - # C++ - | ii + # (Objective-)C++ + | $source_no_preprocess_compile_cpp_regex # Objective-C | mi - # Objective-C++ - | mii # Fortran | f | for | ftn | f90 | f95 | f03 | f08 /x; @@ -111,6 +119,11 @@ my $file_no_compile_regex = qr/ \.(?: $source_preprocess_no_compile_regex | $source_no_preprocess_no_compile_regex)\b /x; +my $file_compile_cpp_regex = qr/ + $cc_regex.+ + \.(?: $source_preprocess_compile_cpp_regex + | $source_no_preprocess_compile_cpp_regex)\b + /x; # Expected (hardening) flags. All flags are used as regexps. my @cflags = ( @@ -132,6 +145,11 @@ my @cflags_stack = ( my @cflags_pie = ( '-fPIE', ); +my @cxxflags = ( + '-g', + '-O(?:2|3)', +); +# @cxxflags_* is the same as @cflags_*. my @cppflags = (); my @cppflags_fortify = ( '-D_FORTIFY_SOURCE=2', @@ -312,7 +330,7 @@ if (not Getopt::Long::GetOptions( 'all' => \$option_all, # Misc. 'color' => \$option_color, - 'arch' => \$option_arch, + 'arch=s' => \$option_arch, 'buildd' => \$option_buildd, )) { require Pod::Usage; @@ -466,6 +484,8 @@ while (my $line = <>) { or $line =~ /^\s*(?:- )?(?:HOST_)?(?:CC|CXX)\s*=\s*$cc_regex\s*$/ or $line =~ /^\s*-- Check for working (?:C|CXX) compiler: / or $line =~ /^\s*(?:echo )?Using [A-Z_]+\s*=\s*/; + # `make` output. + next if $line =~ /^Making [a-z]+ in \S+/; # e.g. "[...] in c++" # Check if additional hardening options were used. Used to ensure # they are used for the complete build. @@ -507,17 +527,21 @@ if ($option_arch) { # Check the specified hardening options, same order as dpkg-buildflags. if ($harden_pie) { @cflags = (@cflags, @cflags_pie); + @cxxflags = (@cxxflags, @cflags_pie); @ldflags = (@ldflags, @ldflags_pie); } if ($harden_stack) { @cflags = (@cflags, @cflags_stack); + @cxxflags = (@cxxflags, @cflags_stack); } if ($harden_fortify) { @cflags = (@cflags, @cflags_fortify); + @cxxflags = (@cxxflags, @cflags_fortify); @cppflags = (@cppflags, @cppflags_fortify); } if ($harden_format) { @cflags = (@cflags, @cflags_format); + @cxxflags = (@cxxflags, @cflags_format); } if ($harden_relro) { @ldflags = (@ldflags, @ldflags_relro); @@ -578,6 +602,14 @@ for (my $i = 0; $i < scalar @input; $i++) { } } + # Assume CXXFLAGS are required when a C++ file is specified in the + # compiler line. + my $compile_cpp = 0; + if ($compile and $line =~ /$file_compile_cpp_regex/) { + $compile = 0; + $compile_cpp = 1; + } + # Check hardening flags. my @missing; if ($compile and not all_flags_used($line, \@missing, @cflags) @@ -585,9 +617,17 @@ for (my $i = 0; $i < scalar @input; $i++) { # with -fPIE as well. It's no error if only PIE flags are missing. and not pic_pie_conflict($line, $harden_pie, \@missing, @cflags_pie) # Assume dpkg-buildflags returns the correct flags. - and not $line =~ /`dpkg-buildflags --get (?:CFLAGS|CXXFLAGS)`/) { + and not $line =~ /`dpkg-buildflags --get CFLAGS`/) { error_flags('CFLAGS missing', \@missing, \%flag_renames, $line); $exit |= 1 << 3; + } elsif ($compile_cpp 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, $harden_pie, \@missing, @cflags_pie) + # Assume dpkg-buildflags returns the correct flags. + and not $line =~ /`dpkg-buildflags --get CXXFLAGS`/) { + error_flags('CXXFLAGS missing', \@missing, \%flag_renames, $line); + $exit |= 1 << 3; } if ($preprocess and not all_flags_used($line, \@missing, @cppflags) # Assume dpkg-buildflags returns the correct flags. @@ -616,18 +656,16 @@ blhc - build log hardening check, checks build logs for missing hardening flags =head1 SYNOPSIS -B [-h -? --help] +B [options] -B [--pie] [--bindnow] [--all] - - --help available options - --version version number and license - --pie force +pie check - --bindnow force +bindbow check --all force +all (+pie, +bindnow) check --arch set architecture (autodetected) + --bindnow force +bindbow check --buildd parser mode for buildds --color use colored output + --pie force +pie check + --help available options + --version version number and license =head1 DESCRIPTION @@ -638,22 +676,6 @@ other important warnings. It's licensed under the GPL 3 or later. =over 8 -=item B<-h -? --help> - -Print available options. - -=item B<--version> - -Print version number and license. - -=item B<--pie> - -Force check for all +pie hardening flags. By default it's auto detected. - -=item B<--bindnow> - -Force check for all +bindnow hardening flags. By default it's auto detected. - =item B<--all> Force check for all +all (+pie, +bindnow) hardening flags. By default it's @@ -665,6 +687,10 @@ 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. +=item B<--bindnow> + +Force check for all +bindnow hardening flags. By default it's auto detected. + =item B<--buildd> Special mode for buildds when automatically parsing log files. The following @@ -683,6 +709,18 @@ detected). Use colored (ANSI) output for warning messages. +=item B<--pie> + +Force check for all +pie hardening flags. By default it's auto detected. + +=item B<-h -? --help> + +Print available options. + +=item B<--version> + +Print version number and license. + =back Auto detection for B<--pie> and B<--bindnow> only works if at least one @@ -694,7 +732,7 @@ all other commands as well. The exit status is a "bit mask", each listed status is ORed when the error condition occurs to get the result. -=over 8 +=over 4 =item B<0>