cc-wrapper: Use set -u throughout

Now is an opportune time to do this, as the infixSalt conversion in
`add-flags.sh` ensures that all the relevant `NIX_*` vars will be
defined even if empty.
This commit is contained in:
John Ericson 2017-08-03 15:34:23 -04:00
parent a8bd415fa0
commit 2493454e13
6 changed files with 68 additions and 50 deletions

View File

@ -1,67 +1,69 @@
hardeningFlags=(fortify stackprotector pic strictoverflow format relro bindnow) hardeningFlags=(fortify stackprotector pic strictoverflow format relro bindnow)
# Intentionally word-split in case 'hardeningEnable' is defined in Nix. # Intentionally word-split in case 'hardeningEnable' is defined in
# Nix. Also, our bootstrap tools version of bash is old enough that
# undefined arrays trip `set -u`.
if [[ -v hardeningEnable[@] ]]; then
hardeningFlags+=(${hardeningEnable[@]}) hardeningFlags+=(${hardeningEnable[@]})
fi
hardeningCFlags=() hardeningCFlags=()
hardeningLDFlags=() hardeningLDFlags=()
declare -A hardeningDisableMap declare -A hardeningDisableMap
# Intentionally word-split in case 'hardeningDisable' is defined in Nix. The # Intentionally word-split in case 'hardeningDisable' is defined in Nix.
# array expansion also prevents undefined variables from causing trouble with for flag in ${hardeningDisable[@]:-IGNORED_KEY} @hardening_unsupported_flags@
# `set -u`.
for flag in ${hardeningDisable[@]} @hardening_unsupported_flags@
do do
hardeningDisableMap[$flag]=1 hardeningDisableMap[$flag]=1
done done
if [[ -n "$NIX_DEBUG" ]]; then if [[ -n "${NIX_DEBUG:-}" ]]; then
printf 'HARDENING: disabled flags:' >&2 printf 'HARDENING: disabled flags:' >&2
(( "${#hardeningDisableMap[@]}" )) && printf ' %q' "${!hardeningDisableMap[@]}" >&2 (( "${#hardeningDisableMap[@]}" )) && printf ' %q' "${!hardeningDisableMap[@]}" >&2
echo >&2 echo >&2
fi fi
if [[ -z "${hardeningDisableMap[all]}" ]]; then if [[ -z "${hardeningDisableMap[all]:-}" ]]; then
if [[ -n "$NIX_DEBUG" ]]; then if [[ -n "${NIX_DEBUG:-}" ]]; then
echo 'HARDENING: Is active (not completely disabled with "all" flag)' >&2; echo 'HARDENING: Is active (not completely disabled with "all" flag)' >&2;
fi fi
for flag in "${hardeningFlags[@]}" for flag in "${hardeningFlags[@]}"
do do
if [[ -z "${hardeningDisableMap[$flag]}" ]]; then if [[ -z "${hardeningDisableMap[$flag]:-}" ]]; then
case $flag in case $flag in
fortify) fortify)
if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: enabling fortify >&2; fi if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling fortify >&2; fi
hardeningCFlags+=('-O2' '-D_FORTIFY_SOURCE=2') hardeningCFlags+=('-O2' '-D_FORTIFY_SOURCE=2')
;; ;;
stackprotector) stackprotector)
if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: enabling stackprotector >&2; fi if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling stackprotector >&2; fi
hardeningCFlags+=('-fstack-protector-strong' '--param' 'ssp-buffer-size=4') hardeningCFlags+=('-fstack-protector-strong' '--param' 'ssp-buffer-size=4')
;; ;;
pie) pie)
if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: enabling CFlags -fPIE >&2; fi if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling CFlags -fPIE >&2; fi
hardeningCFlags+=('-fPIE') hardeningCFlags+=('-fPIE')
if [[ ! ("$*" =~ " -shared " || "$*" =~ " -static ") ]]; then if [[ ! ("$*" =~ " -shared " || "$*" =~ " -static ") ]]; then
if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: enabling LDFlags -pie >&2; fi if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling LDFlags -pie >&2; fi
hardeningLDFlags+=('-pie') hardeningLDFlags+=('-pie')
fi fi
;; ;;
pic) pic)
if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: enabling pic >&2; fi if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling pic >&2; fi
hardeningCFlags+=('-fPIC') hardeningCFlags+=('-fPIC')
;; ;;
strictoverflow) strictoverflow)
if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: enabling strictoverflow >&2; fi if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling strictoverflow >&2; fi
hardeningCFlags+=('-fno-strict-overflow') hardeningCFlags+=('-fno-strict-overflow')
;; ;;
format) format)
if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: enabling format >&2; fi if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling format >&2; fi
hardeningCFlags+=('-Wformat' '-Wformat-security' '-Werror=format-security') hardeningCFlags+=('-Wformat' '-Wformat-security' '-Werror=format-security')
;; ;;
relro) relro)
if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: enabling relro >&2; fi if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling relro >&2; fi
hardeningLDFlags+=('-z' 'relro') hardeningLDFlags+=('-z' 'relro')
;; ;;
bindnow) bindnow)
if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: enabling bindnow >&2; fi if [[ -n "${NIX_DEBUG:-}" ]]; then echo HARDENING: enabling bindnow >&2; fi
hardeningLDFlags+=('-z' 'now') hardeningLDFlags+=('-z' 'now')
;; ;;
*) *)

View File

@ -1,5 +1,5 @@
#! @shell@ #! @shell@
set -e -o pipefail set -eu -o pipefail
shopt -s nullglob shopt -s nullglob
path_backup="$PATH" path_backup="$PATH"
@ -11,12 +11,12 @@ if [[ -n "@coreutils_bin@" && -n "@gnugrep_bin@" ]]; then
PATH="@coreutils_bin@/bin:@gnugrep_bin@/bin" PATH="@coreutils_bin@/bin:@gnugrep_bin@/bin"
fi fi
if [ -n "$NIX_CC_WRAPPER_@infixSalt@_START_HOOK" ]; then if [ -z "${NIX_CC_WRAPPER_@infixSalt@_FLAGS_SET:-}" ]; then
source "$NIX_CC_WRAPPER_@infixSalt@_START_HOOK" source @out@/nix-support/add-flags.sh
fi fi
if [ -z "$NIX_CC_WRAPPER_@infixSalt@_FLAGS_SET" ]; then if [ -n "$NIX_CC_WRAPPER_@infixSalt@_START_HOOK" ]; then
source @out@/nix-support/add-flags.sh source "$NIX_CC_WRAPPER_@infixSalt@_START_HOOK"
fi fi
source @out@/nix-support/utils.sh source @out@/nix-support/utils.sh
@ -36,7 +36,7 @@ declare -i n=0
nParams=${#params[@]} nParams=${#params[@]}
while [ "$n" -lt "$nParams" ]; do while [ "$n" -lt "$nParams" ]; do
p=${params[n]} p=${params[n]}
p2=${params[n+1]} p2=${params[n+1]:-} # handle `p` being last one
if [ "$p" = -c ]; then if [ "$p" = -c ]; then
dontLink=1 dontLink=1
elif [ "$p" = -S ]; then elif [ "$p" = -S ]; then
@ -79,13 +79,13 @@ if [ "$nonFlagArgs" = 0 ]; then
fi fi
# Optionally filter out paths not refering to the store. # Optionally filter out paths not refering to the store.
if [[ "$NIX_ENFORCE_PURITY" = 1 && -n "$NIX_STORE" ]]; then if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "$NIX_STORE" ]]; then
rest=() rest=()
nParams=${#params[@]} nParams=${#params[@]}
declare -i n=0 declare -i n=0
while [ "$n" -lt "$nParams" ]; do while [ "$n" -lt "$nParams" ]; do
p=${params[n]} p=${params[n]}
p2=${params[n+1]} p2=${params[n+1]:-} # handle `p` being last one
if [ "${p:0:3}" = -L/ ] && badPath "${p:2}"; then if [ "${p:0:3}" = -L/ ] && badPath "${p:2}"; then
skip "${p:2}" skip "${p:2}"
elif [ "$p" = -L ] && badPath "$p2"; then elif [ "$p" = -L ] && badPath "$p2"; then
@ -162,13 +162,15 @@ if [ "$*" = -v ]; then
fi fi
# Optionally print debug info. # Optionally print debug info.
if [ -n "$NIX_DEBUG" ]; then if [ -n "${NIX_DEBUG:-}" ]; then
set +u # Old bash workaround, see ld-wrapper for explanation.
echo "extra flags before to @prog@:" >&2 echo "extra flags before to @prog@:" >&2
printf " %q\n" "${extraBefore[@]}" >&2 printf " %q\n" "${extraBefore[@]}" >&2
echo "original flags to @prog@:" >&2 echo "original flags to @prog@:" >&2
printf " %q\n" "${params[@]}" >&2 printf " %q\n" "${params[@]}" >&2
echo "extra flags after to @prog@:" >&2 echo "extra flags after to @prog@:" >&2
printf " %q\n" "${extraAfter[@]}" >&2 printf " %q\n" "${extraAfter[@]}" >&2
set -u
fi fi
if [ -n "$NIX_CC_WRAPPER_@infixSalt@_EXEC_HOOK" ]; then if [ -n "$NIX_CC_WRAPPER_@infixSalt@_EXEC_HOOK" ]; then
@ -176,4 +178,5 @@ if [ -n "$NIX_CC_WRAPPER_@infixSalt@_EXEC_HOOK" ]; then
fi fi
PATH="$path_backup" PATH="$path_backup"
set +u # Old bash workaround, see above.
exec @prog@ "${extraBefore[@]}" "${params[@]}" "${extraAfter[@]}" exec @prog@ "${extraBefore[@]}" "${params[@]}" "${extraAfter[@]}"

View File

@ -1,7 +1,10 @@
#! @shell@ #! @shell@
set -e -o pipefail set -eu -o pipefail
shopt -s nullglob shopt -s nullglob
# N.B. Gnat is not used during bootstrapping, so we don't need to
# worry about the old bash empty array `set -u` workarounds.
path_backup="$PATH" path_backup="$PATH"
# phase separation makes this look useless # phase separation makes this look useless
@ -10,12 +13,12 @@ if [ -n "@coreutils_bin@" ]; then
PATH="@coreutils_bin@/bin" PATH="@coreutils_bin@/bin"
fi fi
if [ -n "$NIX_@infixSalt@_GNAT_WRAPPER_START_HOOK" ]; then if [ -z "${NIX_@infixSalt@_GNAT_WRAPPER_FLAGS_SET:-}" ]; then
source "$NIX_@infixSalt@_GNAT_WRAPPER_START_HOOK" source @out@/nix-support/add-flags.sh
fi fi
if [ -z "$NIX_@infixSalt@_GNAT_WRAPPER_FLAGS_SET" ]; then if [ -n "$NIX_@infixSalt@_GNAT_WRAPPER_START_HOOK" ]; then
source @out@/nix-support/add-flags.sh source "$NIX_@infixSalt@_GNAT_WRAPPER_START_HOOK"
fi fi
source @out@/nix-support/utils.sh source @out@/nix-support/utils.sh
@ -52,7 +55,7 @@ fi
# Optionally filter out paths not refering to the store. # Optionally filter out paths not refering to the store.
params=("$@") params=("$@")
if [[ "$NIX_ENFORCE_PURITY" = 1 && -n "$NIX_STORE" ]]; then if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "$NIX_STORE" ]]; then
rest=() rest=()
for p in "${params[@]}"; do for p in "${params[@]}"; do
if [ "${p:0:3}" = -L/ ] && badPath "${p:2}"; then if [ "${p:0:3}" = -L/ ] && badPath "${p:2}"; then
@ -110,7 +113,7 @@ fi
#fi #fi
# Optionally print debug info. # Optionally print debug info.
if [ -n "$NIX_DEBUG" ]; then if [ -n "${NIX_DEBUG:-}" ]; then
echo "extra flags before to @prog@:" >&2 echo "extra flags before to @prog@:" >&2
printf " %q\n" "${extraBefore[@]}" >&2 printf " %q\n" "${extraBefore[@]}" >&2
echo "original flags to @prog@:" >&2 echo "original flags to @prog@:" >&2

View File

@ -1,7 +1,10 @@
#! @shell@ #! @shell@
set -e -o pipefail set -eu -o pipefail
shopt -s nullglob shopt -s nullglob
# N.B. Gnat is not used during bootstrapping, so we don't need to
# worry about the old bash empty array `set -u` workarounds.
# Add the flags for the GNAT compiler proper. # Add the flags for the GNAT compiler proper.
extraAfter=("--GCC=@out@/bin/gcc") extraAfter=("--GCC=@out@/bin/gcc")
extraBefore=() extraBefore=()
@ -21,7 +24,7 @@ extraBefore=()
#export NIX_@infixSalt@_LDFLAGS_SET=1 #export NIX_@infixSalt@_LDFLAGS_SET=1
# Optionally print debug info. # Optionally print debug info.
if [ -n "$NIX_DEBUG" ]; then if [ -n "${NIX_DEBUG:-}" ]; then
echo "extra flags before to @prog@:" >&2 echo "extra flags before to @prog@:" >&2
printf " %q\n" "${extraBefore[@]}" >&2 printf " %q\n" "${extraBefore[@]}" >&2
echo "original flags to @prog@:" >&2 echo "original flags to @prog@:" >&2

View File

@ -10,12 +10,12 @@ if [ -n "@coreutils_bin@" ]; then
PATH="@coreutils_bin@/bin" PATH="@coreutils_bin@/bin"
fi fi
if [ -n "$NIX_LD_WRAPPER_@infixSalt@_START_HOOK" ]; then if [ -z "${NIX_CC_WRAPPER_@infixSalt@_FLAGS_SET:-}" ]; then
source "$NIX_LD_WRAPPER_@infixSalt@_START_HOOK" source @out@/nix-support/add-flags.sh
fi fi
if [ -z "$NIX_CC_WRAPPER_@infixSalt@_FLAGS_SET" ]; then if [ -n "$NIX_LD_WRAPPER_@infixSalt@_START_HOOK" ]; then
source @out@/nix-support/add-flags.sh source "$NIX_LD_WRAPPER_@infixSalt@_START_HOOK"
fi fi
source @out@/nix-support/utils.sh source @out@/nix-support/utils.sh
@ -23,14 +23,14 @@ source @out@/nix-support/utils.sh
# Optionally filter out paths not refering to the store. # Optionally filter out paths not refering to the store.
expandResponseParams "$@" expandResponseParams "$@"
if [[ "$NIX_ENFORCE_PURITY" = 1 && -n "$NIX_STORE" if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "$NIX_STORE"
&& ( -z "$NIX_@infixSalt@_IGNORE_LD_THROUGH_GCC" || -z "$NIX_@infixSalt@_LDFLAGS_SET" ) ]]; then && ( -z "$NIX_@infixSalt@_IGNORE_LD_THROUGH_GCC" || -z "${NIX_@infixSalt@_LDFLAGS_SET:-}" ) ]]; then
rest=() rest=()
nParams=${#params[@]} nParams=${#params[@]}
declare -i n=0 declare -i n=0
while [ "$n" -lt "$nParams" ]; do while [ "$n" -lt "$nParams" ]; do
p=${params[n]} p=${params[n]}
p2=${params[n+1]} p2=${params[n+1]:-} # handle `p` being last one
if [ "${p:0:3}" = -L/ ] && badPath "${p:2}"; then if [ "${p:0:3}" = -L/ ] && badPath "${p:2}"; then
skip "${p:2}" skip "${p:2}"
elif [ "$p" = -L ] && badPath "$p2"; then elif [ "$p" = -L ] && badPath "$p2"; then
@ -59,7 +59,7 @@ source @out@/nix-support/add-hardening.sh
extraAfter=("${hardeningLDFlags[@]}") extraAfter=("${hardeningLDFlags[@]}")
extraBefore=() extraBefore=()
if [ -z "$NIX_@infixSalt@_LDFLAGS_SET" ]; then if [ -z "${NIX_@infixSalt@_LDFLAGS_SET:-}" ]; then
extraAfter+=($NIX_@infixSalt@_LDFLAGS) extraAfter+=($NIX_@infixSalt@_LDFLAGS)
extraBefore+=($NIX_@infixSalt@_LDFLAGS_BEFORE) extraBefore+=($NIX_@infixSalt@_LDFLAGS_BEFORE)
fi fi
@ -73,7 +73,11 @@ relocatable=
# Find all -L... switches for rpath, and relocatable flags for build id. # Find all -L... switches for rpath, and relocatable flags for build id.
if [ "$NIX_@infixSalt@_DONT_SET_RPATH" != 1 ] || [ "$NIX_@infixSalt@_SET_BUILD_ID" = 1 ]; then if [ "$NIX_@infixSalt@_DONT_SET_RPATH" != 1 ] || [ "$NIX_@infixSalt@_SET_BUILD_ID" = 1 ]; then
prev= prev=
# Old bash thinks empty arrays are undefined, ugh, so temporarily disable
# `set -u`.
set +u
for p in "${extraBefore[@]}" "${params[@]}" "${extraAfter[@]}"; do for p in "${extraBefore[@]}" "${params[@]}" "${extraAfter[@]}"; do
set -u
case "$prev" in case "$prev" in
-L) -L)
libDirs+=("$p") libDirs+=("$p")
@ -119,7 +123,7 @@ if [ "$NIX_@infixSalt@_DONT_SET_RPATH" != 1 ]; then
if [[ "$dir" =~ [/.][/.] ]] && dir2=$(readlink -f "$dir"); then if [[ "$dir" =~ [/.][/.] ]] && dir2=$(readlink -f "$dir"); then
dir="$dir2" dir="$dir2"
fi fi
if [ "${rpaths[$dir]}" ] || [[ "$dir" != "$NIX_STORE"/* ]]; then if [ -n "${rpaths[$dir]:-}" ] || [[ "$dir" != "$NIX_STORE"/* ]]; then
# If the path is not in the store, don't add it to the rpath. # If the path is not in the store, don't add it to the rpath.
# This typically happens for libraries in /tmp that are later # This typically happens for libraries in /tmp that are later
# copied to $out/lib. If not, we're screwed. # copied to $out/lib. If not, we're screwed.
@ -127,9 +131,9 @@ if [ "$NIX_@infixSalt@_DONT_SET_RPATH" != 1 ]; then
fi fi
for path in "$dir"/lib*.so; do for path in "$dir"/lib*.so; do
file="${path##*/}" file="${path##*/}"
if [ "${libs[$file]}" ]; then if [ "${libs[$file]:-}" ]; then
libs["$file"]= libs["$file"]=
if [ ! "${rpaths[$dir]}" ]; then if [ -z "${rpaths[$dir]:-}" ]; then
rpaths["$dir"]=1 rpaths["$dir"]=1
extraAfter+=(-rpath "$dir") extraAfter+=(-rpath "$dir")
fi fi
@ -147,13 +151,15 @@ fi
# Optionally print debug info. # Optionally print debug info.
if [ -n "$NIX_DEBUG" ]; then if [ -n "${NIX_DEBUG:-}" ]; then
set +u # Old bash workaround, see above.
echo "extra flags before to @prog@:" >&2 echo "extra flags before to @prog@:" >&2
printf " %q\n" "${extraBefore[@]}" >&2 printf " %q\n" "${extraBefore[@]}" >&2
echo "original flags to @prog@:" >&2 echo "original flags to @prog@:" >&2
printf " %q\n" "${params[@]}" >&2 printf " %q\n" "${params[@]}" >&2
echo "extra flags after to @prog@:" >&2 echo "extra flags after to @prog@:" >&2
printf " %q\n" "${extraAfter[@]}" >&2 printf " %q\n" "${extraAfter[@]}" >&2
set -u
fi fi
if [ -n "$NIX_LD_WRAPPER_@infixSalt@_EXEC_HOOK" ]; then if [ -n "$NIX_LD_WRAPPER_@infixSalt@_EXEC_HOOK" ]; then
@ -161,4 +167,5 @@ if [ -n "$NIX_LD_WRAPPER_@infixSalt@_EXEC_HOOK" ]; then
fi fi
PATH="$path_backup" PATH="$path_backup"
set +u # Old bash workaround, see above.
exec @prog@ "${extraBefore[@]}" "${params[@]}" "${extraAfter[@]}" exec @prog@ "${extraBefore[@]}" "${params[@]}" "${extraAfter[@]}"

View File

@ -1,5 +1,5 @@
skip () { skip () {
if [ -n "$NIX_DEBUG" ]; then if [ -n "${NIX_DEBUG:-}" ]; then
echo "skipping impure path $1" >&2 echo "skipping impure path $1" >&2
fi fi
} }