X-Git-Url: https://ruderich.org/simon/gitweb/?p=blhc%2Fblhc.git;a=blobdiff_plain;f=bin%2Fblhc;h=1d35e0ba489008f5c2eee8bab499256e0445d2b3;hp=38466e4cca55187111ec244577cd12461dc384ad;hb=d6333e474554290abc21a27bbd1de7e0be1a4e10;hpb=cb6df05acfa32fe06b4f980422fd4b38c3239c0e diff --git a/bin/blhc b/bin/blhc index 38466e4..1d35e0b 100755 --- a/bin/blhc +++ b/bin/blhc @@ -31,8 +31,10 @@ our $VERSION = '0.01'; # Regex to catch compiler commands. my $cc_regex = qr/ - (? \$option_help, - 'version' => \$option_version, + 'help|h|?' => \$option_help, + 'version' => \$option_version, # Hardening options. - 'pie' => \$option_pie, - 'bindnow' => \$option_bindnow, - 'all' => \$option_all, + 'pie' => \$option_pie, + 'bindnow' => \$option_bindnow, + 'all' => \$option_all, + # Ignore. + 'ignore-flag=s' => \@option_ignore_flag, + 'ignore-line=s' => \@option_ignore_line, # Misc. - 'color' => \$option_color, - 'arch=s' => \$option_arch, - 'buildd' => \$option_buildd, + 'color' => \$option_color, + 'arch=s' => \$option_arch, + 'buildd' => \$option_buildd, ) or scalar @ARGV == 0) { require Pod::Usage; @@ -480,16 +487,36 @@ if ($option_all) { $option_bindnow = 1; } +# Strip flags which should be ignored. +if (scalar @option_ignore_flag > 0) { + my %ignores = map { $_ => 1 } @option_ignore_flag; + foreach my $flags (@flag_refs) { + @{$flags} = grep { + # Flag found as string. + not exists $ignores{$_} + # Flag found as string representation of regexp. + and (not defined $flag_renames{$_} + or not exists $ignores{$flag_renames{$_}}) + } @{$flags}; + } +} + # Precompile all flag regexps. any_flags_used(), all_flags_used() get a lot # faster with this. foreach my $flags (@flag_refs_all) { @{$flags} = compile_flag_regexp(\%flag_renames, @{$flags}); } +# Precompile ignore line regexps, also anchor at beginning and end of line. +foreach my $ignore (@option_ignore_line) { + $ignore = qr/^$ignore$/; +} + # Final exit code. my $exit = 0; -FILE: foreach my $file (@ARGV) { +FILE: +foreach my $file (@ARGV) { print "checking '$file'...\n" if scalar @ARGV > 1; open my $fh, '<', $file or die "$!: $file"; @@ -686,10 +713,10 @@ FILE: 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 ($cpu =~ /^(?:ia64|alpha|mips|mipsel|hppa)$/ or $arch eq 'arm') { $harden_stack = 0; } - if ($cpu =~ /^(ia64|hppa|avr32)$/) { + if ($cpu =~ /^(?:ia64|hppa|avr32)$/) { $harden_relro = 0; $harden_bindnow = 0; } @@ -726,9 +753,15 @@ FILE: foreach my $file (@ARGV) { @ldflags = (@ldflags, @def_ldflags_bindnow); } +LINE: for (my $i = 0; $i < scalar @input; $i++) { my $line = $input[$i]; + # Ignore line if requested. + foreach my $ignore (@option_ignore_line) { + next LINE if $line =~ /$ignore/; + } + my $skip = 0; if (is_non_verbose_build($line, $input[$i + 1], \$skip)) { if (not $option_buildd) { @@ -932,8 +965,12 @@ B [I] Idpkg-buildpackage build log fileE..> =head1 DESCRIPTION -blhc is a small tool which checks build logs for missing hardening flags and -other important warnings. It's licensed under the GPL 3 or later. +blhc is a small tool which checks build logs for missing hardening flags. It's +licensed under the GPL 3 or later. + +It's designed to check build logs generated by Debian's dpkg-buildpackage (or +tools using dpkg-buildpackage like pbuilder or the official buildd build logs) +to help maintainers detect missing hardening flags in their packages. =head1 OPTIONS @@ -963,8 +1000,8 @@ changes are in effect: =item -Print tags instead of normal warnings, see README file for a list of possible -tags. +Print tags instead of normal warnings, see L for a list of +possible tags. =item @@ -981,6 +1018,23 @@ Don't require Term::ANSIColor. Use colored (ANSI) output for warning messages. +=item B<--ignore-flag> I + +Don't print an error when the specific flag is missing in a compiler line. +I is a string. + +Used to prevent false positives. This option can be specified multiple times. + +=item B<--ignore-line> I + +Ignore lines matching the given Perl regex. I is automatically anchored +at the beginning and end of the line to prevent false negatives. + +B: Not the input lines are checked, but the lines which are displayed in +warnings (which have line continuation resolved). + +Used to prevent false positives. This option can be specified multiple times. + =item B<--pie> Force check for all +pie hardening flags. By default it's auto detected. @@ -999,6 +1053,84 @@ Auto detection for B<--pie> and B<--bindnow> only works if at least one command uses the required hardening flag (e.g. -fPIE). Then it's required for all other commands as well. +=head1 EXAMPLES + +Normal usage, parse a single log file. + + blhc path/to/log/file + +Parse multiple log files. The exit code is ORed over all files. + + blhc path/to/directory/with/log/files/* + +Don't treat missing C<-g> as error: + + blhc --ignore-flag -g path/to/log/file + +Ignore lines consisting exactly of C<./script gcc file> which would cause a +false positive. + + blhc --ignore-line '\./script gcc file' path/to/log/file + +Ignore lines matching C<./script gcc file> somewhere in the line. + + blhc --ignore-line '.*\./script gcc file.*' path/to/log/file + +Use blhc with pbuilder. + + pbuilder path/to/package.dsc | tee path/log/file + blhc path/to/file || echo flags missing + +=head1 BUILDD TAGS + +The following tags are used in I<--buildd> mode. In braces the additional data +which is displayed. + +=over 2 + +=item + +B + +The package uses hardening-wrapper which intercepts calls to gcc and adds +hardening flags. The build log doesn't contain any hardening flags and thus +can't be checked by blhc. + +=item + +B (summary of hidden lines) + +Build log contains lines which hide the real compiler flags. For example: + + CC test-a.c + CC test-b.c + CC test-c.c + LD test + +Most of the time either C or C in +F fixes builds with hidden compiler flags. Sometimes C<.SILENT> +in a F must be removed. And as last resort the F must be +patched to remove the C<@>s hiding the real compiler commands. + +=item + +B (summary of missing flags) + +CPPFLAGS, CFLAGS, CXXFLAGS, LDFLAGS missing. + +=item + +B (version) + +=item + +B + +No compiler commands were detected. Either the log contains none or they were +not correctly detected by blhc (please report the bug in this case). + +=back + =head1 EXIT STATUS The exit status is a "bit mask", each listed status is ORed when the error @@ -1036,6 +1168,9 @@ Hardening wrapper detected, no tests performed. Simon Ruderich, Esimon@ruderich.orgE +Thanks to to Bernhard R. Link Ebrlink@debian.orgE and Jaria Alto +Ejari.aalto@cante.netE for their valuable input and suggestions. + =head1 COPYRIGHT AND LICENSE Copyright (C) 2012 by Simon Ruderich @@ -1053,4 +1188,8 @@ 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 . +=head1 SEE ALSO + +L, L + =cut