From 84fdf4bf7f490f08a970b571af743d9a9637bff2 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Tue, 1 Apr 2025 14:44:29 -0400 Subject: [PATCH] Review compiler options for Clang and GCC Signed-off-by: Juan Cruz Viotti --- cmake/FindPCRE2.cmake | 4 ++ cmake/Findmpdecimal.cmake | 4 ++ cmake/common/compiler/options.cmake | 55 +++++++++++++++++++++++++-- cmake/common/targets/executable.cmake | 23 +++++++++++ 4 files changed, 83 insertions(+), 3 deletions(-) diff --git a/cmake/FindPCRE2.cmake b/cmake/FindPCRE2.cmake index a3cf0ae4d..fae13deed 100644 --- a/cmake/FindPCRE2.cmake +++ b/cmake/FindPCRE2.cmake @@ -103,6 +103,10 @@ if(NOT PCRE2_FOUND) target_compile_options(sljit PRIVATE -Wno-conditional-uninitialized) endif() + if(SOURCEMETA_COMPILER_GCC) + target_compile_options(sljit PRIVATE -Wno-stringop-overflow) + endif() + if(SOURCEMETA_COMPILER_MSVC) target_compile_options(sljit PRIVATE /sdl-) target_compile_options(sljit PRIVATE /wd4701) diff --git a/cmake/Findmpdecimal.cmake b/cmake/Findmpdecimal.cmake index 01c31c74f..24808d57f 100644 --- a/cmake/Findmpdecimal.cmake +++ b/cmake/Findmpdecimal.cmake @@ -60,6 +60,10 @@ if(NOT mpdecimal_FOUND) target_compile_options(mpdecimal PRIVATE -Wno-conversion) endif() + if(SOURCEMETA_COMPILER_GCC) + target_compile_options(mpdecimal PRIVATE -Wno-stringop-overflow) + endif() + if(SOURCEMETA_COMPILER_MSVC) target_compile_options(mpdecimal PRIVATE /wd4200) target_compile_options(mpdecimal PRIVATE /wd4702) diff --git a/cmake/common/compiler/options.cmake b/cmake/common/compiler/options.cmake index 1c14a1678..e502f45fb 100644 --- a/cmake/common/compiler/options.cmake +++ b/cmake/common/compiler/options.cmake @@ -41,7 +41,6 @@ function(sourcemeta_add_default_options visibility target) $<$,$>:-Woverloaded-virtual> $<$,$>:-Winvalid-offsetof> -funroll-loops - -fstrict-aliasing -ftree-vectorize # To improve how much GCC/Clang will vectorize @@ -51,7 +50,41 @@ function(sourcemeta_add_default_options visibility target) # multiplication wraps around using twos-complement representation # See https://users.cs.utah.edu/~regehr/papers/overflow12.pdf # See https://www.postgresql.org/message-id/1689.1134422394@sss.pgh.pa.us - -fwrapv) + -fwrapv + + # See https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html + -Wformat + -Wformat=2 + -Werror=format-security + -fstack-protector-strong) + + # Control-flow protection: requires hardware and OS support + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + # -fcf-protection uses Intel CET (Control-flow Enforcement Technology) + # Requires OS kernel support, primarily available on Linux + if(LINUX) + target_compile_options("${target}" ${visibility} -fcf-protection=full) + endif() + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + # -mbranch-protection uses ARM BTI/PAC, requires Linux kernel 5.8+ + if(LINUX) + target_compile_options("${target}" ${visibility} -mbranch-protection=standard) + endif() + endif() + + # _FORTIFY_SOURCE requires optimization (-O1 or higher), so only enable in Release builds + # First undefine to avoid conflicts, then define + target_compile_options("${target}" ${visibility} + $<$:-U_FORTIFY_SOURCE> + $<$:-U_FORTIFY_SOURCE>) + target_compile_definitions("${target}" ${visibility} + $<$:_FORTIFY_SOURCE=3> + $<$:_FORTIFY_SOURCE=3>) + + # _GLIBCXX_ASSERTIONS is libstdc++ (GNU) specific, not applicable to libc++ (LLVM/macOS) + if(NOT APPLE AND SOURCEMETA_COMPILER_GCC) + target_compile_definitions("${target}" ${visibility} $<$:_GLIBCXX_ASSERTIONS>) + endif() endif() if(SOURCEMETA_COMPILER_LLVM) @@ -80,6 +113,11 @@ function(sourcemeta_add_default_options visibility target) -fvectorize # Enable vectorization of straight-line code for performance -fslp-vectorize) + + # See https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html + target_compile_options("${target}" ${visibility} + $<$:-fno-delete-null-pointer-checks -fno-strict-aliasing -ftrivial-auto-var-init=zero> + $<$:-fno-delete-null-pointer-checks -fno-strict-aliasing -ftrivial-auto-var-init=zero>) elseif(SOURCEMETA_COMPILER_GCC) target_compile_options("${target}" ${visibility} -fno-trapping-math @@ -88,7 +126,18 @@ function(sourcemeta_add_default_options visibility target) # GCC seems to print a lot of false-positives here -Wno-free-nonheap-object # Disables runtime type information - $<$,$>:-fno-rtti>) + $<$,$>:-fno-rtti> + + # See https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html + -Wtrampolines + -Wbidi-chars=any + -fstack-clash-protection + -fstrict-flex-arrays=3) + + # See https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html + target_compile_options("${target}" ${visibility} + $<$:-fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -ftrivial-auto-var-init=zero> + $<$:-fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -ftrivial-auto-var-init=zero>) endif() endfunction() diff --git a/cmake/common/targets/executable.cmake b/cmake/common/targets/executable.cmake index 4f5db98f8..f662dc64e 100644 --- a/cmake/common/targets/executable.cmake +++ b/cmake/common/targets/executable.cmake @@ -30,5 +30,28 @@ function(sourcemeta_executable) add_executable("${TARGET_NAME}" ${SOURCEMETA_EXECUTABLE_SOURCES}) sourcemeta_add_default_options(PRIVATE ${TARGET_NAME}) + + # See https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html + # Position Independent Executable (PIE) for ASLR support + if(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC) + target_compile_options(${TARGET_NAME} PRIVATE + $<$:-fPIE> + $<$:-fPIE>) + target_link_options(${TARGET_NAME} PRIVATE + $<$:-pie> + $<$:-pie>) + endif() + + # Linux-specific ELF linker hardening options + if(LINUX AND (SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC)) + target_link_options(${TARGET_NAME} PRIVATE + "LINKER:-z,nodlopen" + "LINKER:-z,noexecstack" + "LINKER:-z,relro" + "LINKER:-z,now" + "LINKER:--as-needed" + "LINKER:--no-copy-dt-needed-entries") + endif() + set_target_properties("${TARGET_NAME}" PROPERTIES FOLDER "${FOLDER_NAME}") endfunction()