nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at devShellTools-shell 170 lines 6.8 kB view raw
1declare -a hardeningCFlagsAfter=() 2declare -a hardeningCFlagsBefore=() 3 4declare -A hardeningEnableMap=() 5 6# Intentionally word-split in case 'NIX_HARDENING_ENABLE' is defined in Nix. The 7# array expansion also prevents undefined variables from causing trouble with 8# `set -u`. 9for flag in ${NIX_HARDENING_ENABLE_@suffixSalt@-}; do 10 hardeningEnableMap["$flag"]=1 11done 12 13 14# fortify3 implies fortify enablement - make explicit before 15# we filter unsupported flags because unsupporting fortify3 16# doesn't mean we should unsupport fortify too 17if [[ -n "${hardeningEnableMap[fortify3]-}" ]]; then 18 hardeningEnableMap["fortify"]=1 19fi 20 21# strictflexarrays3 implies strictflexarrays1 enablement - make explicit before 22# we filter unsupported flags because unsupporting strictflexarrays3 23# doesn't mean we should unsupport strictflexarrays1 too 24if [[ -n "${hardeningEnableMap[strictflexarrays3]-}" ]]; then 25 hardeningEnableMap["strictflexarrays1"]=1 26fi 27 28 29# Remove unsupported flags. 30for flag in @hardening_unsupported_flags@; do 31 unset -v "hardeningEnableMap[$flag]" 32 # fortify being unsupported implies fortify3 is unsupported 33 if [[ "$flag" = 'fortify' ]] ; then 34 unset -v "hardeningEnableMap['fortify3']" 35 fi 36 # strictflexarrays1 being unsupported implies strictflexarrays3 is unsupported 37 if [[ "$flag" = 'strictflexarrays1' ]] ; then 38 unset -v "hardeningEnableMap['strictflexarrays3']" 39 fi 40done 41 42 43# now make fortify and fortify3 mutually exclusive 44if [[ -n "${hardeningEnableMap[fortify3]-}" ]]; then 45 unset -v "hardeningEnableMap['fortify']" 46fi 47 48# now make strictflexarrays1 and strictflexarrays3 mutually exclusive 49if [[ -n "${hardeningEnableMap[strictflexarrays3]-}" ]]; then 50 unset -v "hardeningEnableMap['strictflexarrays1']" 51fi 52 53 54if (( "${NIX_DEBUG:-0}" >= 1 )); then 55 declare -a allHardeningFlags=(fortify fortify3 shadowstack stackprotector stackclashprotection nostrictaliasing pacret strictflexarrays1 strictflexarrays3 pie pic strictoverflow format trivialautovarinit zerocallusedregs) 56 declare -A hardeningDisableMap=() 57 58 # Determine which flags were effectively disabled so we can report below. 59 for flag in "${allHardeningFlags[@]}"; do 60 if [[ -z "${hardeningEnableMap[$flag]-}" ]]; then 61 hardeningDisableMap["$flag"]=1 62 fi 63 done 64 65 printf 'HARDENING: disabled flags:' >&2 66 (( "${#hardeningDisableMap[@]}" )) && printf ' %q' "${!hardeningDisableMap[@]}" >&2 67 echo >&2 68 69 if (( "${#hardeningEnableMap[@]}" )); then 70 echo 'HARDENING: Is active (not completely disabled with "all" flag)' >&2; 71 fi 72fi 73 74for flag in "${!hardeningEnableMap[@]}"; do 75 case $flag in 76 fortify | fortify3) 77 # Use -U_FORTIFY_SOURCE to avoid warnings on toolchains that explicitly 78 # set -D_FORTIFY_SOURCE=0 (like 'clang -fsanitize=address'). 79 hardeningCFlagsBefore+=('-O2' '-U_FORTIFY_SOURCE') 80 # Unset any _FORTIFY_SOURCE values the command-line may have set before 81 # enforcing our own value, avoiding (potentially fatal) redefinition 82 # warnings 83 hardeningCFlagsAfter+=('-U_FORTIFY_SOURCE') 84 case $flag in 85 fortify) 86 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling fortify >&2; fi 87 hardeningCFlagsAfter+=('-D_FORTIFY_SOURCE=2') 88 ;; 89 fortify3) 90 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling fortify3 >&2; fi 91 hardeningCFlagsAfter+=('-D_FORTIFY_SOURCE=3') 92 ;; 93 *) 94 # Ignore unsupported. 95 ;; 96 esac 97 ;; 98 shadowstack) 99 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling shadowstack >&2; fi 100 hardeningCFlagsBefore+=('-fcf-protection=return') 101 ;; 102 strictflexarrays1) 103 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling strictflexarrays1 >&2; fi 104 hardeningCFlagsBefore+=('-fstrict-flex-arrays=1') 105 ;; 106 strictflexarrays3) 107 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling strictflexarrays3 >&2; fi 108 hardeningCFlagsBefore+=('-fstrict-flex-arrays=3') 109 ;; 110 pacret) 111 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling pacret >&2; fi 112 hardeningCFlagsBefore+=('-mbranch-protection=pac-ret') 113 ;; 114 stackprotector) 115 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling stackprotector >&2; fi 116 hardeningCFlagsBefore+=('-fstack-protector-strong' '--param' 'ssp-buffer-size=4') 117 ;; 118 stackclashprotection) 119 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling stack-clash-protection >&2; fi 120 hardeningCFlagsBefore+=('-fstack-clash-protection') 121 ;; 122 nostrictaliasing) 123 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling nostrictaliasing >&2; fi 124 hardeningCFlagsBefore+=('-fno-strict-aliasing') 125 ;; 126 pie) 127 # NB: we do not use `+=` here, because PIE flags must occur before any PIC flags 128 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling CFlags -fPIE >&2; fi 129 hardeningCFlagsBefore=('-fPIE' "${hardeningCFlagsBefore[@]}") 130 if [[ ! (" ${params[*]} " =~ " -shared " || " ${params[*]} " =~ " -static ") ]]; then 131 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling LDFlags -pie >&2; fi 132 hardeningCFlagsBefore=('-pie' "${hardeningCFlagsBefore[@]}") 133 fi 134 ;; 135 pic) 136 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling pic >&2; fi 137 hardeningCFlagsBefore+=('-fPIC') 138 ;; 139 strictoverflow) 140 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling strictoverflow >&2; fi 141 if (( @isClang@ )); then 142 # In Clang, -fno-strict-overflow only serves to set -fwrapv and is 143 # reported as an unused CLI argument if -fwrapv or -fno-wrapv is set 144 # explicitly, so we side step that by doing the conversion here. 145 # 146 # See: https://github.com/llvm/llvm-project/blob/llvmorg-16.0.6/clang/lib/Driver/ToolChains/Clang.cpp#L6315 147 # 148 hardeningCFlagsBefore+=('-fwrapv') 149 else 150 hardeningCFlagsBefore+=('-fno-strict-overflow') 151 fi 152 ;; 153 trivialautovarinit) 154 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling trivialautovarinit >&2; fi 155 hardeningCFlagsBefore+=('-ftrivial-auto-var-init=pattern') 156 ;; 157 format) 158 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling format >&2; fi 159 hardeningCFlagsBefore+=('-Wformat' '-Wformat-security' '-Werror=format-security') 160 ;; 161 zerocallusedregs) 162 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling zerocallusedregs >&2; fi 163 hardeningCFlagsBefore+=('-fzero-call-used-regs=used-gpr') 164 ;; 165 *) 166 # Ignore unsupported. Checked in Nix that at least *some* 167 # tool supports each flag. 168 ;; 169 esac 170done