X-Git-Url: https://ruderich.org/simon/gitweb/?p=blhc%2Fblhc.git;a=blobdiff_plain;f=bin%2Fblhc;h=193297e4b7fdba4ffb6095074b4c3cea0774e055;hp=f11ba111028c3949fd526a8f89eee47f316fba2c;hb=c00a6af3163584d9bbe5f0742f9ed001c202e564;hpb=14b61d421e2479318cb2971acc1c94812f5a8ac1 diff --git a/bin/blhc b/bin/blhc index f11ba11..193297e 100755 --- a/bin/blhc +++ b/bin/blhc @@ -222,11 +222,17 @@ my @def_cflags_fortify = ( # fortify needs at least -O1, but -O2 is recommended anyway ); my @def_cflags_stack = ( - '-fstack-protector', + '-fstack-protector', # keep first, used by cflags_stack_broken() '--param[= ]ssp-buffer-size=4', ); my @def_cflags_stack_strong = ( - '-fstack-protector-strong', + '-fstack-protector-strong', # keep first, used by cflags_stack_broken() +); +my @def_cflags_stack_bad = ( + # Blacklist all stack protector options for simplicity. + '-fno-stack-protector', + '-fno-stack-protector-all', + '-fno-stack-protector-strong', ); my @def_cflags_pie = ( '-fPIE', @@ -270,6 +276,7 @@ my @flag_refs = ( \@def_cflags_fortify, \@def_cflags_stack, \@def_cflags_stack_strong, + \@def_cflags_stack_bad, \@def_cflags_pie, \@def_cxxflags, \@def_cppflags, @@ -427,39 +434,63 @@ sub all_flags_used { @{$missing_flags_ref} = @missing_flags; return 0; } +# Check if any of \@bad_flags occurs after $good_flag. Doesn't check if +# $good_flag is present. +sub flag_overwritten { + my ($line, $good_flag, $bad_flags) = @_; -sub cppflags_fortify_broken { - my ($line, $missing_flags) = @_; - - if (not any_flags_used($line, @def_cppflags_fortify_bad)) { + if (not any_flags_used($line, @{$bad_flags})) { return 0; } - # $def_cppflags_fortify[0] must be -D_FORTIFY_SOURCE=2! - my $fortify_source = $def_cppflags_fortify[0]; - - # Some build systems enable/disable fortify source multiple times, check - # the final result. - my $disable_pos = 0; - foreach my $flag (@def_cppflags_fortify_bad) { + my $bad_pos = 0; + foreach my $flag (@{$bad_flags}) { while ($line =~ /$flag/g) { - if ($disable_pos < $+[0]) { - $disable_pos = $+[0]; + if ($bad_pos < $+[0]) { + $bad_pos = $+[0]; } } } - my $enable_pos = 0; - while ($line =~ /$fortify_source/g) { - $enable_pos = $+[0]; + my $good_pos = 0; + while ($line =~ /$good_flag/g) { + $good_pos = $+[0]; } - if ($enable_pos > $disable_pos) { + if ($good_pos > $bad_pos) { return 0; } + return 1; +} + +sub cppflags_fortify_broken { + my ($line, $missing_flags) = @_; + # $def_cppflags_fortify[0] must be -D_FORTIFY_SOURCE=2! + my $fortify_source = $def_cppflags_fortify[0]; + + # Some build systems enable/disable fortify source multiple times, check + # the final result. + if (not flag_overwritten($line, + $fortify_source, + \@def_cppflags_fortify_bad)) { + return 0; + } push @{$missing_flags}, $fortify_source; return 1; } +sub cflags_stack_broken { + my ($line, $missing_flags, $strong) = @_; + + my $flag = $strong ? $def_cflags_stack_strong[0] + : $def_cflags_stack[0]; + + if (not flag_overwritten($line, $flag, \@def_cflags_stack_bad)) { + return 0; + } + push @{$missing_flags}, $flag; + return 1; +} + # Modifies $missing_flags_ref array. sub pic_pie_conflict { my ($line, $pie, $missing_flags_ref, @flags_pie) = @_; @@ -1042,7 +1073,7 @@ foreach my $file (@ARGV) { # treated as a normal compiler line. next if $line =~ m{^\s*rm\s+}; # Some build systems emit "gcc > file". - next if $line =~ m{$cc_regex_normal\s*>\s*\S+}; + next if $line =~ m{$cc_regex_normal\s*>\s*\S+}o; # Check if additional hardening options were used. Used to ensure # they are used for the complete build. @@ -1345,7 +1376,10 @@ LINE: # Check hardening flags. my @missing; - if ($compile and not all_flags_used($line, \@missing, @cflags) + if ($compile and (not all_flags_used($line, \@missing, @cflags) + or (($harden_stack or $harden_stack_strong) + and cflags_stack_broken($line, \@missing, + $harden_stack_strong))) # 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.