1#! /usr/bin/perl 2use strict; 3use warnings; 4use File::Spec qw(rel2abs); 5use File::Basename; 6 7my @args = (); 8my $enabled = 0; 9my $debug = 0; 10my $debug_fd = *STDERR; 11 12# Set up defaults 13my %default; 14$default{'DEB_BUILD_HARDENING'}=0; 15$default{'DEB_BUILD_HARDENING_DEBUG'}=0; 16 17# Architecture settings 18# #OS# #ARCH# 19$default{'DEB_BUILD_HARDENING_RELRO'}=1; 20$default{'DEB_BUILD_HARDENING_BINDNOW'}=1; 21 22# System settings 23my $system_conf = '/etc/hardening-wrapper.conf'; 24if (-r $system_conf) { 25 open(CONF,$system_conf) || warn "Cannot read $system_conf\n"; 26 while (my $line = <CONF>) { 27 if ($line =~ /^\s*(DEB_BUILD_HARDENING[_A-Z]*)\s*=\s*(\d)$/) { 28 $default{$1}=$2+0; 29 } 30 } 31 close(CONF); 32} 33 34# Environment settings 35$enabled = defined($ENV{'DEB_BUILD_HARDENING'}) ? 36 $ENV{'DEB_BUILD_HARDENING'} : 37 $default{'DEB_BUILD_HARDENING'}; 38$debug = defined($ENV{'DEB_BUILD_HARDENING_DEBUG'}) ? 39 $ENV{'DEB_BUILD_HARDENING_DEBUG'} : 40 $default{'DEB_BUILD_HARDENING_DEBUG'}; 41my $force_relro = defined($ENV{'DEB_BUILD_HARDENING_RELRO'}) ? 42 $ENV{'DEB_BUILD_HARDENING_RELRO'} : 43 $default{'DEB_BUILD_HARDENING_RELRO'}; 44my $force_bindnow = defined($ENV{'DEB_BUILD_HARDENING_BINDNOW'}) ? 45 $ENV{'DEB_BUILD_HARDENING_BINDNOW'} : 46 $default{'DEB_BUILD_HARDENING_BINDNOW'}; 47 48if ($enabled) { 49 # Scan arguments 50 my $index = 0; 51 foreach my $arg (@ARGV) { 52 if ($arg eq "relro" && $index>0 && $ARGV[$index-1] eq "-z") { 53 $force_relro = 0; 54 } 55 if ($arg eq "now" && $index>0 && $ARGV[$index-1] eq "-z") { 56 $force_bindnow = 0; 57 } 58 $index++; 59 } 60 61 if ($force_relro) { 62 push(@args,'-z','relro'); 63 } 64 if ($force_bindnow) { 65 push(@args,'-z','now'); 66 } 67} 68 69my $self = "hardened-ld"; 70my $link = ""; 71my $arg0 = File::Spec->rel2abs(basename($0),dirname($0)); 72my $tool = $arg0; 73if ($tool =~ /$self$/ || defined($ENV{'HARDENING_USE_USR_BIN'})) { 74 $tool = "/usr/bin/ld"; 75} 76 77if (defined($ENV{'DEB_BUILD_HARDENING_DEBUG_OUTPUT'})) { 78 $debug_fd = undef; 79 if (!open($debug_fd, ">>$ENV{'DEB_BUILD_HARDENING_DEBUG_OUTPUT'}")) { 80 die "Cannot open $ENV{'DEB_BUILD_HARDENING_DEBUG_OUTPUT'}: $!\n"; 81 } 82} 83 84sub resolve_link($) 85{ 86 my $origin = $_[0]; 87 my $link = readlink($origin); 88 return File::Spec->rel2abs($link,dirname($origin)); 89} 90 91while (-l $tool && ($link = resolve_link($tool)) !~ /$self$/) { 92 $tool = $link; 93} 94if (-x "$tool.real") { 95 $tool = "$tool.real"; 96} 97# Abort if we ended up on a circular symlink resolution 98if ($tool eq $arg0) { 99 my $short = $tool; 100 $short =~ s/.*\///g; 101 print STDERR "$tool: not found (maybe $short is not installed?)\n"; 102 exit(127); 103} 104my @target = ($tool, @args, @ARGV); 105 106print $debug_fd join(" ",@target),"\n" if ($debug); 107 108exec @target or die "Unable to exec $target[0]: $!\n"; 109