Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enables Conditional Compiler Protections #6743

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 33 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,40 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU|AppleClang|Clang")
"The compiler ${CMAKE_C_COMPILER_ID} does not support -fvisibility=hidden"
)
endif(NOT CC_SUPPORTS_VISIBILITY_HIDDEN)
# security options go here - these are not supported by all compilers
# first and foremost, do we have LTO?
check_c_compiler_flag(-flto CC_SUPPORTS_LTO)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can be pretty sure that if the -fsanitize=cfi works, -flto will work as well, so no need to check this separately unless you want to provide a very specific error message saying what is wrong (and you do not have such a message here).

To enable Clang’s available CFI schemes, use the flag -fsanitize=cfi. You can also enable a subset of available schemes. As currently implemented, all schemes rely on link-time optimization (LTO); so it is required to specify -flto, and the linker used must support LTO, for example via the gold plugin.

if(NOT CC_SUPPORTS_LTO)
message("The compiler ${CMAKE_C_COMPILER_ID} does not support LTO - CFI disabled and FORTIFY might increase binary size significantly")
endif()
# if we are building on a GLIBC environment, FORTIFY is available
include(CheckCSourceCompiles)
set(CMAKE_REQUIRED_FLAGS -Werror)
set(CMAKE_REQUIRED_DEFINITIONS -D_FORTIFY_SOURCE)
# If this build succeeds, _FORTIFY_SOURCE is not available
check_c_source_compiles("
#include <string.h>
int main() {
char buffer[8];
strcpy(buffer, \"hello world\");
}" FORTIFY_NOT_AVAILABLE)
if(NOT FORTIFY_NOT_AVAILABLE)
add_compile_options(-D_FORTIFY_SOURCE=2)
if(CC_SUPPORTS_LTO)
add_compile_options(-flto)
endif()
else()
message(STATUS "Compiler ${CMAKE_C_COMPILER_ID} does not support -D_FORTIFY_SOURCE=1")
endif()
# CFI is currently supported by clang
check_c_compiler_flag(-fsanitize=cfi CC_SUPPORTS_CFI)
# for CFI to work, we need LTO and Hidden Visibility
if(CC_SUPPORTS_CFI AND CC_SUPPORTS_LTO AND CC_SUPPORTS_VISIBILITY_HIDDEN)
add_compile_options(-fvisibility=hidden -flto -fsanitize=cfi)
else()
message(STATUS "Compiler ${CMAKE_C_COMPILER_ID} does not support CFI")
endif()
endif()

# On Windows, default to only include Release builds so MSBuild.exe 'just works'
if(WIN32 AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES
Expand Down