diff options
| author | Theo Buehler <tb@openbsd.org> | 2026-08-29 10:09:40 +0200 |
|---|---|---|
| committer | Theo Buehler <tb@openbsd.org> | 2026-08-29 10:09:40 +0200 |
| commit | 89d3233a7e770ca43c9168fe2672f9c27615b87d (patch) | |
| tree | 0ac99ee599105d46406fe2a0d1f93987a43285fa | |
| parent | b4f65f728b7ff48f53b5876212e85fadc4ac90c5 (diff) | |
| parent | 66b2316045444c7dbf91139ae7ebe5f9b96a0a4a (diff) | |
| download | portable-89d3233a7e770ca43c9168fe2672f9c27615b87d.tar.gz portable-89d3233a7e770ca43c9168fe2672f9c27615b87d.tar.bz2 portable-89d3233a7e770ca43c9168fe2672f9c27615b87d.zip | |
Land #1366 - align hardening flags in cmake with autotools build
| -rw-r--r-- | CMakeLists.txt | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a59ddc..18fb262 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -159,6 +159,99 @@ if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") | |||
| 159 | add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-pointer-sign>) | 159 | add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-pointer-sign>) |
| 160 | endif() | 160 | endif() |
| 161 | 161 | ||
| 162 | # Exploit-mitigation flags, matching the default-on hardening the autotools | ||
| 163 | # build applies (m4/check-hardening-options.m4). The CMake build shipped none | ||
| 164 | # of these, so a cmake-built libcrypto/libssl/libtls and openssl(1) had no | ||
| 165 | # stack protector, no _FORTIFY_SOURCE, no RELRO/BIND_NOW and no CET, and the | ||
| 166 | # mingw DLLs missed the DEP/ASLR opt-ins. MSVC is left to its own toolchain | ||
| 167 | # defaults, exactly as that m4 (which only drives gcc/clang/mingw flags) does. | ||
| 168 | # Every flag is probed before use so unsupported targets simply skip it. | ||
| 169 | option(ENABLE_HARDENING | ||
| 170 | "Enable options to frustrate memory corruption exploits" ON) | ||
| 171 | option(ENABLE_WINDOWS_SSP | ||
| 172 | "Build stack smashing protection on Windows (requires libssp)" OFF) | ||
| 173 | |||
| 174 | if(ENABLE_HARDENING AND NOT MSVC AND | ||
| 175 | (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")) | ||
| 176 | include(CheckCCompilerFlag) | ||
| 177 | |||
| 178 | macro(add_harden_cflag _flag _var) | ||
| 179 | check_c_compiler_flag("${_flag}" ${_var}) | ||
| 180 | if(${_var}) | ||
| 181 | add_compile_options($<$<COMPILE_LANGUAGE:C>:${_flag}>) | ||
| 182 | endif() | ||
| 183 | endmacro() | ||
| 184 | |||
| 185 | # CMake 3.16 predates check_linker_flag, so probe link flags by linking. | ||
| 186 | macro(add_harden_ldflag _flag _var) | ||
| 187 | set(_saved_link_options "${CMAKE_REQUIRED_LINK_OPTIONS}") | ||
| 188 | set(CMAKE_REQUIRED_LINK_OPTIONS "${_flag}") | ||
| 189 | check_c_source_compiles("int main(void){return 0;}" ${_var}) | ||
| 190 | set(CMAKE_REQUIRED_LINK_OPTIONS "${_saved_link_options}") | ||
| 191 | if(${_var}) | ||
| 192 | add_link_options("${_flag}") | ||
| 193 | endif() | ||
| 194 | endmacro() | ||
| 195 | |||
| 196 | # Do not optimize based on signed arithmetic overflow. | ||
| 197 | add_harden_cflag(-fno-strict-overflow HAVE_CFLAG_FNO_STRICT_OVERFLOW) | ||
| 198 | |||
| 199 | if(NOT WIN32) | ||
| 200 | # _FORTIFY_SOURCE needs an optimizing build and warns without one, | ||
| 201 | # so probe it at -O2 and only apply it to non-Debug C compiles. | ||
| 202 | set(_saved_req_flags "${CMAKE_REQUIRED_FLAGS}") | ||
| 203 | set(CMAKE_REQUIRED_FLAGS | ||
| 204 | "-O2 -Werror -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2") | ||
| 205 | check_c_source_compiles("#include <string.h> | ||
| 206 | int main(void){char b[8];const char *s=\"x\";strcpy(b,s);return b[0];}" | ||
| 207 | HAVE_CFLAG_FORTIFY_SOURCE) | ||
| 208 | set(CMAKE_REQUIRED_FLAGS "${_saved_req_flags}") | ||
| 209 | if(HAVE_CFLAG_FORTIFY_SOURCE) | ||
| 210 | add_compile_options( | ||
| 211 | "$<$<AND:$<COMPILE_LANGUAGE:C>,$<NOT:$<CONFIG:Debug>>>:-U_FORTIFY_SOURCE>" | ||
| 212 | "$<$<AND:$<COMPILE_LANGUAGE:C>,$<NOT:$<CONFIG:Debug>>>:-D_FORTIFY_SOURCE=2>") | ||
| 213 | endif() | ||
| 214 | |||
| 215 | # Read-only relocations, resolved at load time. wasm has no | ||
| 216 | # ELF loader and wasm-ld only warns about unknown -z values, | ||
| 217 | # so the probe false-positives on Emscripten; skip it there. | ||
| 218 | if(NOT EMSCRIPTEN) | ||
| 219 | add_harden_ldflag(-Wl,-z,relro HAVE_LDFLAG_Z_RELRO) | ||
| 220 | add_harden_ldflag(-Wl,-z,now HAVE_LDFLAG_Z_NOW) | ||
| 221 | endif() | ||
| 222 | else() | ||
| 223 | # Windows (mingw) DEP, ASLR and high-entropy ASLR opt-ins. | ||
| 224 | add_harden_ldflag(-Wl,--nxcompat HAVE_LDFLAG_NXCOMPAT) | ||
| 225 | add_harden_ldflag(-Wl,--dynamicbase HAVE_LDFLAG_DYNAMICBASE) | ||
| 226 | add_harden_ldflag(-Wl,--high-entropy-va HAVE_LDFLAG_HIGH_ENTROPY_VA) | ||
| 227 | endif() | ||
| 228 | |||
| 229 | # Stack smashing protection. On Windows this pulls in libssp, so it is | ||
| 230 | # opt-in there, mirroring --enable-windows-ssp. Emscripten accepts the | ||
| 231 | # flag (and the frameless probe links), but its libc has no | ||
| 232 | # __stack_chk_guard/__stack_chk_fail, so any protected frame fails to | ||
| 233 | # link; it provides its own stack checks (-sSTACK_OVERFLOW_CHECK). | ||
| 234 | if(NOT EMSCRIPTEN AND (NOT WIN32 OR ENABLE_WINDOWS_SSP)) | ||
| 235 | check_c_compiler_flag(-fstack-protector-strong | ||
| 236 | HAVE_CFLAG_STACK_PROTECTOR_STRONG) | ||
| 237 | if(HAVE_CFLAG_STACK_PROTECTOR_STRONG) | ||
| 238 | add_compile_options( | ||
| 239 | $<$<COMPILE_LANGUAGE:C>:-fstack-protector-strong>) | ||
| 240 | else() | ||
| 241 | add_harden_cflag(-fstack-protector-all | ||
| 242 | HAVE_CFLAG_STACK_PROTECTOR_ALL) | ||
| 243 | endif() | ||
| 244 | if(WIN32) | ||
| 245 | set(PLATFORM_LIBS ${PLATFORM_LIBS} ssp) | ||
| 246 | endif() | ||
| 247 | endif() | ||
| 248 | |||
| 249 | # Control-flow integrity (Intel CET); unsupported on Darwin. | ||
| 250 | if(NOT APPLE) | ||
| 251 | add_harden_cflag(-fcf-protection=full HAVE_CFLAG_CF_PROTECTION) | ||
| 252 | endif() | ||
| 253 | endif() | ||
| 254 | |||
| 162 | if(WIN32) | 255 | if(WIN32) |
| 163 | add_definitions(-D_CRT_SECURE_NO_WARNINGS) | 256 | add_definitions(-D_CRT_SECURE_NO_WARNINGS) |
| 164 | add_definitions(-D_CRT_DEPRECATED_NO_WARNINGS) | 257 | add_definitions(-D_CRT_DEPRECATED_NO_WARNINGS) |
