Skip to content

Commit 422363a

Browse files
Adopt the OpenSSF Compiler Options Hardening Guide for C and C++
1 parent ab7af2b commit 422363a

File tree

4 files changed

+170
-6
lines changed

4 files changed

+170
-6
lines changed

cmake/cmake-harden.cmake

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# Copyright 2025 Holepunch Inc
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
# Downloaded on 2026-03-16 from https://github.com/holepunchto/cmake-harden/blob/main/cmake-harden.cmake
16+
# Changelog
17+
# 2026-03-16
18+
# add -Wextra
19+
# add -Wsign-conversion
20+
# add -Wbidi-chars=any
21+
# add -U_FORTIFY_SOURCE
22+
# add -D_FORTIFY_SOURCE=3
23+
# add -D_GLIBCXX_ASSERTIONS
24+
# add -fcf-protection=full
25+
# add -mbranch-protection=standard
26+
# add -Wl,-z,nodlopen
27+
# add -Wl,--as-needed
28+
# add -Wl,--no-copy-dt-needed-entries
29+
# add fexceptions
30+
# add fhardened
31+
# rename GCC compiler to GNU compiler to apply to gcc and g++
32+
# Check Linker Flag and use LINKER: prefix
33+
34+
cmake_minimum_required(VERSION 3.19)
35+
36+
include_guard()
37+
38+
include(CheckCompilerFlag)
39+
include(CheckLinkerFlag)
40+
41+
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html
42+
43+
macro(add_hardened_compiler_flags)
44+
foreach(flag ${ARGV})
45+
check_compiler_flag(${lang} ${flag} supports_${flag})
46+
47+
if(supports_${flag})
48+
target_compile_options(${target} PRIVATE ${flag})
49+
endif()
50+
endforeach()
51+
endmacro()
52+
53+
macro(add_hardened_linker_flags)
54+
foreach(flag ${ARGV})
55+
check_linker_flag(${lang} LINKER:${flag} supports_${flag})
56+
57+
if(supports_${flag})
58+
target_link_options(${target} PRIVATE LINKER:${flag})
59+
endif()
60+
endforeach()
61+
endmacro()
62+
63+
macro(harden_posix)
64+
add_hardened_compiler_flags(
65+
-Wall
66+
-Wextra
67+
-Wformat
68+
-Wformat=2
69+
-Wconversion
70+
-Wsign-conversion
71+
-Wimplicit-fallthrough
72+
-Wbidi-chars=any
73+
-Werror=format-security
74+
-Werror=implicit
75+
-Werror=incompatible-pointer-types
76+
-Werror=int-conversion
77+
-U_FORTIFY_SOURCE
78+
-D_FORTIFY_SOURCE=3
79+
-D_GLIBCXX_ASSERTIONS
80+
-fstrict-flex-arrays=3
81+
-fcf-protection=full
82+
-mbranch-protection=standard
83+
-fno-delete-null-pointer-checks
84+
-fno-strict-overflow
85+
-fno-strict-aliasing
86+
-ftrivial-auto-var-init=zero
87+
-fexceptions
88+
-fhardened
89+
)
90+
91+
# The SHARED and MODULE library targets have by default position independent code enabled : https://cmake.org/cmake/help/latest/variable/CMAKE_POSITION_INDEPENDENT_CODE.html
92+
add_hardened_linker_flags(
93+
-z,nodlopen
94+
-z,noexecstack
95+
-z,relro
96+
-z,now
97+
--as-needed
98+
--no-copy-dt-needed-entries
99+
)
100+
101+
if(runtime)
102+
add_hardened_compiler_flags(
103+
-fstack-clash-protection
104+
-fstack-protector-strong
105+
)
106+
endif()
107+
endmacro()
108+
109+
macro(harden_clang)
110+
harden_posix()
111+
endmacro()
112+
113+
macro(harden_gnu)
114+
harden_posix()
115+
116+
add_hardened_compiler_flags(
117+
-Wtrampolines
118+
)
119+
endmacro()
120+
121+
macro(harden_msvc)
122+
message(WARNING "Compiler hardening is not yet supported for MSVC")
123+
endmacro()
124+
125+
function(harden target)
126+
set(option_keywords
127+
C
128+
CXX
129+
RUNTIME
130+
)
131+
132+
cmake_parse_arguments(
133+
PARSE_ARGV 1 ARGV "${option_keywords}" "" ""
134+
)
135+
136+
set(runtime ${ARGV_RUNTIME})
137+
138+
if(ARGV_CXX)
139+
set(lang CXX)
140+
else()
141+
set(lang C)
142+
endif()
143+
144+
set(compiler ${CMAKE_${lang}_COMPILER_ID})
145+
146+
if(compiler MATCHES "Clang")
147+
harden_clang()
148+
elseif(compiler MATCHES "GNU")
149+
harden_gnu()
150+
elseif(compiler MATCHES "MSVC")
151+
harden_msvc()
152+
endif()
153+
endfunction()

java/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ find_package(JNI REQUIRED)
66
find_package(Java REQUIRED)
77
include(UseJava)
88

9+
## Need to enable dlopen
10+
get_target_property(old_link_options ${CPP_LIBRARY_NAME} LINK_OPTIONS)
11+
if(old)
12+
string(REPLACE "-Wl,-z,nodlopen" "" new_link_options "${old_link_options}")
13+
set_target_properties(${CPP_LIBRARY_NAME} PROPERTIES LINK_OPTIONS "${new_link_options}")
14+
endif()
15+
916
set(SWIG_LINKED_TO_RELEASE ON CACHE BOOL "Is your SWIG generated library linked to the release or debug version of FesapiCpp ?")
1017

1118
message("Generating SWIG Java files...")

python/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
find_package(SWIG 3.0 REQUIRED)
44
find_package(Python3 REQUIRED)
55

6+
## Need to enable dlopen
7+
get_target_property(old_link_options ${CPP_LIBRARY_NAME} LINK_OPTIONS)
8+
if(old)
9+
string(REPLACE "-Wl,-z,nodlopen" "" new_link_options "${old_link_options}")
10+
set_target_properties(${CPP_LIBRARY_NAME} PROPERTIES LINK_OPTIONS "${new_link_options}")
11+
endif()
12+
613
set (Fesapi_PYTHON_VERSION ${Fesapi_VERSION_MAJOR}.${Fesapi_VERSION_MINOR}.${Fesapi_VERSION_PATCH})
714

815
set(SWIG_LINKED_TO_RELEASE ON CACHE BOOL "Is your SWIG generated library linked to the release or debug version of FesapiCpp ?")

src/CMakeLists.txt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,12 @@ set (EML_PREFIX_2_0 "eml2_0")
4040
set (EML_PREFIX_2_3 "eml2_3")
4141

4242
# Define the compile options according to the compiler
43-
target_compile_options(${CPP_LIBRARY_NAME} PRIVATE
43+
include(${FESAPI_ROOT_DIR}/cmake/cmake-harden.cmake)
44+
harden(${CPP_LIBRARY_NAME} CXX RUNTIME)
45+
target_compile_options(${CPP_LIBRARY_NAME} PRIVATE
4446
$<$<CXX_COMPILER_ID:MSVC>:/bigobj>
4547
$<$<CXX_COMPILER_ID:MSVC>:/MP>
4648
$<$<CXX_COMPILER_ID:MSVC>:/W4>
47-
$<$<CXX_COMPILER_ID:GNU>:-Wall>
48-
$<$<CXX_COMPILER_ID:GNU>:-Wextra>
49-
$<$<CXX_COMPILER_ID:GNU>:-Wcast-qual>
50-
$<$<CXX_COMPILER_ID:GNU>:-pedantic>
51-
$<$<CXX_COMPILER_ID:CLANG>:-Weverything>
5249
)
5350
if (WITH_RESQML2_2)
5451
target_compile_definitions(${CPP_LIBRARY_NAME} PUBLIC "-DWITH_RESQML2_2")

0 commit comments

Comments
 (0)