aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo Buehler <tb@openbsd.org>2026-08-29 10:09:40 +0200
committerTheo Buehler <tb@openbsd.org>2026-08-29 10:09:40 +0200
commit89d3233a7e770ca43c9168fe2672f9c27615b87d (patch)
tree0ac99ee599105d46406fe2a0d1f93987a43285fa
parentb4f65f728b7ff48f53b5876212e85fadc4ac90c5 (diff)
parent66b2316045444c7dbf91139ae7ebe5f9b96a0a4a (diff)
downloadportable-89d3233a7e770ca43c9168fe2672f9c27615b87d.tar.gz
portable-89d3233a7e770ca43c9168fe2672f9c27615b87d.tar.bz2
portable-89d3233a7e770ca43c9168fe2672f9c27615b87d.zip
Land #1366 - align hardening flags in cmake with autotools build
-rw-r--r--CMakeLists.txt93
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>)
160endif() 160endif()
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.
169option(ENABLE_HARDENING
170 "Enable options to frustrate memory corruption exploits" ON)
171option(ENABLE_WINDOWS_SSP
172 "Build stack smashing protection on Windows (requires libssp)" OFF)
173
174if(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>
206int 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()
253endif()
254
162if(WIN32) 255if(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)