cc-wrapper: add `glibcxxassertions` hardening flag (#414987)

authored by

Robert Scott and committed by
GitHub
d3afbb6d 6e8f5691

+49 -1
+3
doc/redirects.json
··· 574 574 "strictflexarrays3": [ 575 575 "index.html#strictflexarrays3" 576 576 ], 577 + "glibcxxassertions": [ 578 + "index.html#glibcxxassertions" 579 + ], 577 580 "tester-shfmt": [ 578 581 "index.html#tester-shfmt" 579 582 ],
+6
doc/stdenv/stdenv.chapter.md
··· 1688 1688 sorry, unimplemented: __builtin_clear_padding not supported for variable length aggregates 1689 1689 ``` 1690 1690 1691 + #### `glibcxxassertions` {#glibcxxassertions} 1692 + 1693 + Adds the `-D_GLIBCXX_ASSERTIONS` compiler flag. This flag only has an effect on libstdc++ targets, and when defined, enables extra error checking in the form of precondition assertions, such as bounds checking in c++ strings and null pointer checks when dereferencing c++ smart pointers. 1694 + 1695 + These checks may have an impact on performance in some cases. 1696 + 1691 1697 #### `pacret` {#pacret} 1692 1698 1693 1699 This flag adds the `-mbranch-protection=pac-ret` compiler option on aarch64-linux targets. This uses ARM v8.3's Pointer Authentication feature to sign function return pointers before adding them to the stack. The pointer's authenticity is then validated before returning to its destination. This dramatically increases the difficulty of ROP exploitation techniques.
+5 -1
pkgs/build-support/cc-wrapper/add-hardening.sh
··· 52 52 53 53 54 54 if (( "${NIX_DEBUG:-0}" >= 1 )); then 55 - declare -a allHardeningFlags=(fortify fortify3 shadowstack stackprotector stackclashprotection nostrictaliasing pacret strictflexarrays1 strictflexarrays3 pie pic strictoverflow format trivialautovarinit zerocallusedregs) 55 + declare -a allHardeningFlags=(fortify fortify3 shadowstack stackprotector stackclashprotection nostrictaliasing pacret strictflexarrays1 strictflexarrays3 pie pic strictoverflow glibcxxassertions format trivialautovarinit zerocallusedregs) 56 56 declare -A hardeningDisableMap=() 57 57 58 58 # Determine which flags were effectively disabled so we can report below. ··· 110 110 pacret) 111 111 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling pacret >&2; fi 112 112 hardeningCFlagsBefore+=('-mbranch-protection=pac-ret') 113 + ;; 114 + glibcxxassertions) 115 + if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling glibcxxassertions >&2; fi 116 + hardeningCFlagsBefore+=('-D_GLIBCXX_ASSERTIONS') 113 117 ;; 114 118 stackprotector) 115 119 if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling stackprotector >&2; fi
+3
pkgs/by-name/ar/arrow-cpp/package.nix
··· 178 178 ZSTD_ROOT = zstd.dev; 179 179 }; 180 180 181 + # fails tests on glibc with this enabled 182 + hardeningDisable = [ "glibcxxassertions" ]; 183 + 181 184 preConfigure = '' 182 185 patchShebangs build-support/ 183 186 substituteInPlace "src/arrow/vendored/datetime/tz.cpp" \
+1
pkgs/stdenv/generic/make-derivation.nix
··· 154 154 "pie" 155 155 "relro" 156 156 "stackprotector" 157 + "glibcxxassertions" 157 158 "stackclashprotection" 158 159 "strictoverflow" 159 160 "trivialautovarinit"
+30
pkgs/test/cc-wrapper/hardening.nix
··· 4 4 runCommand, 5 5 runCommandWith, 6 6 runCommandCC, 7 + writeText, 7 8 bintools, 8 9 hello, 9 10 debian-devscripts, ··· 39 40 f3exampleWithStdEnv = writeCBinWithStdenv ./fortify3-example.c; 40 41 41 42 flexArrF2ExampleWithStdEnv = writeCBinWithStdenv ./flex-arrays-fortify-example.c; 43 + 44 + checkGlibcxxassertionsWithStdEnv = 45 + expectDefined: 46 + writeCBinWithStdenv ( 47 + writeText "main.cpp" '' 48 + #if${if expectDefined then "n" else ""}def _GLIBCXX_ASSERTIONS 49 + #error "Expected _GLIBCXX_ASSERTIONS to be ${if expectDefined then "" else "un"}defined" 50 + #endif 51 + int main() {} 52 + '' 53 + ); 42 54 43 55 # for when we need a slightly more complicated program 44 56 helloWithStdEnv = ··· 502 514 hardeningEnable = [ "shadowstack" ]; 503 515 }) false; 504 516 517 + glibcxxassertionsExplicitEnabled = checkGlibcxxassertionsWithStdEnv true stdenv { 518 + hardeningEnable = [ "glibcxxassertions" ]; 519 + }; 520 + 505 521 bindNowExplicitDisabled = 506 522 checkTestBin 507 523 (f2exampleWithStdEnv stdenv { ··· 697 713 hardeningDisable = [ "shadowstack" ]; 698 714 }) true; 699 715 716 + glibcxxassertionsExplicitDisabled = checkGlibcxxassertionsWithStdEnv false stdenv { 717 + hardeningDisable = [ "glibcxxassertions" ]; 718 + }; 719 + 700 720 # most flags can't be "unsupported" by compiler alone and 701 721 # binutils doesn't have an accessible hardeningUnsupportedFlags 702 722 # mechanism, so can only test a couple of flags through altered ··· 897 917 expectFailure = true; 898 918 }; 899 919 920 + glibcxxassertionsStdenvUnsupp = 921 + checkGlibcxxassertionsWithStdEnv false (stdenvUnsupport [ "glibcxxassertions" ]) 922 + { 923 + hardeningEnable = [ "glibcxxassertions" ]; 924 + }; 925 + 900 926 fortify3EnabledEnvEnablesFortify1 = 901 927 checkTestBin 902 928 (f1exampleWithStdEnv stdenv { ··· 1107 1133 allExplicitDisabledShadowStack = shadowStackTest (f1exampleWithStdEnv stdenv { 1108 1134 hardeningDisable = [ "all" ]; 1109 1135 }) true; 1136 + 1137 + glibcxxassertionsExplicitDisabled = checkGlibcxxassertionsWithStdEnv false stdenv { 1138 + hardeningDisable = [ "all" ]; 1139 + }; 1110 1140 } 1111 1141 ) 1112 1142 )
+1
pkgs/top-level/variants.nix
··· 164 164 "shadowstack" 165 165 "nostrictaliasing" 166 166 "pacret" 167 + "glibcxxassertions" 167 168 "trivialautovarinit" 168 169 ] 169 170 ) super'.stdenv;