#! /usr/bin/perl use strict; use warnings; use File::Spec qw(rel2abs); use File::Basename; my @args = (); my $enabled = 0; my $debug = 0; my $debug_fd = *STDERR; # Set up defaults my %default; $default{'DEB_BUILD_HARDENING'}=0; $default{'DEB_BUILD_HARDENING_DEBUG'}=0; # Architecture settings # #OS# #ARCH# $default{'DEB_BUILD_HARDENING_RELRO'}=1; $default{'DEB_BUILD_HARDENING_BINDNOW'}=1; # System settings my $system_conf = '/etc/hardening-wrapper.conf'; if (-r $system_conf) { open(CONF,$system_conf) || warn "Cannot read $system_conf\n"; while (my $line = ) { if ($line =~ /^\s*(DEB_BUILD_HARDENING[_A-Z]*)\s*=\s*(\d)$/) { $default{$1}=$2+0; } } close(CONF); } # Environment settings $enabled = defined($ENV{'DEB_BUILD_HARDENING'}) ? $ENV{'DEB_BUILD_HARDENING'} : $default{'DEB_BUILD_HARDENING'}; $debug = defined($ENV{'DEB_BUILD_HARDENING_DEBUG'}) ? $ENV{'DEB_BUILD_HARDENING_DEBUG'} : $default{'DEB_BUILD_HARDENING_DEBUG'}; my $force_relro = defined($ENV{'DEB_BUILD_HARDENING_RELRO'}) ? $ENV{'DEB_BUILD_HARDENING_RELRO'} : $default{'DEB_BUILD_HARDENING_RELRO'}; my $force_bindnow = defined($ENV{'DEB_BUILD_HARDENING_BINDNOW'}) ? $ENV{'DEB_BUILD_HARDENING_BINDNOW'} : $default{'DEB_BUILD_HARDENING_BINDNOW'}; if ($enabled) { # Scan arguments my $index = 0; foreach my $arg (@ARGV) { if ($arg eq "relro" && $index>0 && $ARGV[$index-1] eq "-z") { $force_relro = 0; } if ($arg eq "now" && $index>0 && $ARGV[$index-1] eq "-z") { $force_bindnow = 0; } $index++; } if ($force_relro) { push(@args,'-z','relro'); } if ($force_bindnow) { push(@args,'-z','now'); } } my $self = "hardened-ld"; my $link = ""; my $arg0 = File::Spec->rel2abs(basename($0),dirname($0)); my $tool = $arg0; if ($tool =~ /$self$/ || defined($ENV{'HARDENING_USE_USR_BIN'})) { $tool = "/usr/bin/ld"; } if (defined($ENV{'DEB_BUILD_HARDENING_DEBUG_OUTPUT'})) { $debug_fd = undef; if (!open($debug_fd, ">>$ENV{'DEB_BUILD_HARDENING_DEBUG_OUTPUT'}")) { die "Cannot open $ENV{'DEB_BUILD_HARDENING_DEBUG_OUTPUT'}: $!\n"; } } sub resolve_link($) { my $origin = $_[0]; my $link = readlink($origin); return File::Spec->rel2abs($link,dirname($origin)); } while (-l $tool && ($link = resolve_link($tool)) !~ /$self$/) { $tool = $link; } if (-x "$tool.real") { $tool = "$tool.real"; } # Abort if we ended up on a circular symlink resolution if ($tool eq $arg0) { my $short = $tool; $short =~ s/.*\///g; print STDERR "$tool: not found (maybe $short is not installed?)\n"; exit(127); } my @target = ($tool, @args, @ARGV); print $debug_fd join(" ",@target),"\n" if ($debug); exec @target or die "Unable to exec $target[0]: $!\n";