blob: cbe5dda09320f6ad68241bf82e521fea29d421bf [file] [log] [blame]
#!/bin/bash
# Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This script ensures that "--sysroot" is passed to whatever it is wrapping.
#
# It also adds hardened flags to gcc invocation. The hardened flags are:
# 1. -fstack-protector-all
# 2. -fPIE
# 3. -pie
# 4. -D_FORTIFY_SOURCE=2
#
# It can disable -fPIE -pie by checking if -nopie is passed to gcc. In this
# case it removes -nopie as it is a non-standard flag.
#
# There is a similar hardening wrapper that wraps ld and adds -z now -z relro
# to the link command line (see ldwrapper).
#
# To use:
# mv <tool> <tool>.real
# ln -s <path_to_sysroot_wrapper> <tool>
non_fstack_flags=(-D__KERNEL__ -fno-stack-protector -fstack-protector-all\
-fstack-protector -nodefaultlibs -nostdlib)
non_fPIE_flags=(-D__KERNEL__ -fPIC -fPIE -fno-PIC -fno-PIE -fno-pic -fno-pie\
-fpic -fpie -nopie -nostartfiles -nostdlib -pie -static)
non_pie_flags=(-D__KERNEL__ -A -fno-PIC -fno-PIE -fno-pic -fno-pie\
-nopie -nostartfiles -nostdlib -pie -r --shared -shared -static)
non_standard_flags=(-nopie)
fstack_status=1
fPIE_status=1
pie_status=1
now_status=1
# Arguments: array, value
# Returns 0 if value is in the array
# Returns 1 otherwise
function value_in_array
{
local array=($(echo "$1"))
local value=$2
for array_value in ${array[@]}
do
if [[ $array_value == $value ]]
then
return 0
fi
done
return 1
}
# Arguments: flag
# Checks if flag is in the array non_${flag}_flags.
# If so, sets ${flag}_status to 0.
function set_status_for_flag
{
local flag="$1"
local status_var_name="${flag}_status"
local flags_var_name="non_${flag}_flags"
local array=$(eval echo "\${$flags_var_name[@]}")
local args="$2"
for var in ${args[@]}
do
if [[ ${!status_var_name} -eq 1 ]]
then
value_in_array "$(echo ${array[@]})" "$var"
if [[ $? -eq 0 ]]
then
eval $status_var_name=0
break
fi
fi
done
}
set_status_for_flag "fstack" "$(echo $@)"
set_status_for_flag "fPIE" "$(echo $@)"
set_status_for_flag "pie" "$(echo $@)"
set_status_for_flag "now" "$(echo $@)"
SYSROOT_WRAPPER_LOG=/tmp/sysroot_wrapper.error
HARDENED_FLAGS=""
if [[ $fstack_status -eq 1 ]]
then
HARDENED_FLAGS+=" -fstack-protector-all"
fi
if [[ $fPIE_status -eq 1 ]]
then
HARDENED_FLAGS+=" -fPIE"
fi
if [[ $pie_status -eq 1 ]]
then
HARDENED_FLAGS+=" -pie"
fi
HARDENED_FLAGS+=" -D_FORTIFY_SOURCE=2"
for arg in "$@"
do
for non_standard_flag in ${non_standard_flags[@]}
do
if [[ "$arg" != "$non_standard_flag" ]]
then
new_args=("${new_args[@]}" "$arg")
fi
done
done
new_args=(${HARDENED_FLAGS} "${new_args[@]}")
if [ -n "$SYSROOT" ] ; then
exec "${0}.real" --sysroot="$SYSROOT" "${new_args[@]}"
else
if [[ ! -f $SYSROOT_WRAPPER_LOG ]]; then
touch $SYSROOT_WRAPPER_LOG
chmod a+w $SYSROOT_WRAPPER_LOG
fi
echo "Invocation with missing SYSROOT: ${0} ${new_args[@]}" >> $SYSROOT_WRAPPER_LOG
exec "${0}.real" "${new_args[@]}"
fi