From 230d01388f1f1ca6dd36d6931bc177841b8977fc Mon Sep 17 00:00:00 2001 From: Ben Thompson Date: Tue, 5 Sep 2017 13:49:35 -0500 Subject: [PATCH] Add compiler flag checks and hardening flags --- CMakeLists.txt | 25 ++++++++++++----- check_compiler_flag.cmake | 56 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 check_compiler_flag.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 56030c154..51d2e7a8a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,17 +106,30 @@ if(NOT AWK_EXECUTABLE) message(FATAL_ERROR "awk not found!") endif() +INCLUDE(check_compiler_flag.cmake) -FOREACH(BUILD_TYPE RELEASE RELWITHDEBINFO MINSIZEREL) - SET(CMAKE_CXX_FLAGS_${BUILD_TYPE} "-g -O3 -fno-strict-aliasing -Wall -fno-tree-vectorize -DDBUG_OFF -DHAVE_CONFIG_H") - SET(CMAKE_C_FLAGS_${BUILD_TYPE} "-g -O3 -fno-strict-aliasing -Wall -fno-tree-vectorize -DDBUG_OFF -DHAVE_CONFIG_H") -ENDFOREACH() +MY_CHECK_AND_SET_COMPILER_FLAG("-g -O3 -fno-strict-aliasing -Wall -fno-tree-vectorize -DDBUG_OFF -DHAVE_CONFIG_H" RELEASE RELWITHDEBINFO MINSIZEREL) +MY_CHECK_AND_SET_COMPILER_FLAG("-ggdb3 -fno-tree-vectorize -DSAFE_MUTEX -DSAFEMALLOC -DENABLED_DEBUG_SYNC -O0 -Wall -D_DEBUG -DHAVE_CONFIG_H" DEBUG) -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb3 -fno-tree-vectorize -DSAFE_MUTEX -DSAFEMALLOC -DENABLED_DEBUG_SYNC -O0 -Wall -D_DEBUG -DHAVE_CONFIG_H") -SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb3 -fno-tree-vectorize -DSAFE_MUTEX -DSAFEMALLOC -DENABLED_DEBUG_SYNC -O0 -Wall -D _DEBUG -DHAVE_CONFIG_H") +# enable security hardening features, like most distributions do +# in our benchmarks that costs about ~1% of performance, depending on the load +IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "4.6") + SET(security_default OFF) +ELSE() + SET(security_default ON) +ENDIF() +OPTION(SECURITY_HARDENED "Use security-enhancing compiler features (stack protector, relro, etc)" ${security_default}) +IF(SECURITY_HARDENED) + # security-enhancing flags + MY_CHECK_AND_SET_COMPILER_FLAG("-pie -fPIC") + MY_CHECK_AND_SET_COMPILER_FLAG("-Wl,-z,relro,-z,now") + MY_CHECK_AND_SET_COMPILER_FLAG("-fstack-protector --param=ssp-buffer-size=4") + MY_CHECK_AND_SET_COMPILER_FLAG("-D_FORTIFY_SOURCE=2" RELEASE RELWITHDEBINFO) +ENDIF() SET (ENGINE_LDFLAGS "-Wl,--no-as-needed -Wl,--add-needed") + FIND_PACKAGE(Boost 1.53.0 REQUIRED COMPONENTS system filesystem thread regex date_time) SET (ENGINE_LIBDIR "${INSTALL_ENGINE}/lib") diff --git a/check_compiler_flag.cmake b/check_compiler_flag.cmake new file mode 100644 index 000000000..6b29ac5ab --- /dev/null +++ b/check_compiler_flag.cmake @@ -0,0 +1,56 @@ +include(CheckCSourceCompiles) +include(CheckCXXSourceCompiles) +# We need some extra FAIL_REGEX patterns +# Note that CHECK_C_SOURCE_COMPILES is a misnomer, it will also link. +SET(fail_patterns + FAIL_REGEX "argument unused during compilation" + FAIL_REGEX "unsupported .*option" + FAIL_REGEX "unknown .*option" + FAIL_REGEX "unrecognized .*option" + FAIL_REGEX "ignoring unknown option" + FAIL_REGEX "warning:.*ignored" + FAIL_REGEX "warning:.*is valid for.*but not for" + FAIL_REGEX "warning:.*redefined" + FAIL_REGEX "[Ww]arning: [Oo]ption" + ) + +MACRO (MY_CHECK_C_COMPILER_FLAG flag) + STRING(REGEX REPLACE "[-,= +]" "_" result "have_C_${flag}") + SET(SAVE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${flag}") + CHECK_C_SOURCE_COMPILES("int main(void) { return 0; }" ${result} + ${fail_patterns}) + SET(CMAKE_REQUIRED_FLAGS "${SAVE_CMAKE_REQUIRED_FLAGS}") +ENDMACRO() + +MACRO (MY_CHECK_CXX_COMPILER_FLAG flag) + STRING(REGEX REPLACE "[-,= +]" "_" result "have_CXX_${flag}") + SET(SAVE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${flag}") + CHECK_CXX_SOURCE_COMPILES("int main(void) { return 0; }" ${result} + ${fail_patterns}) + SET(CMAKE_REQUIRED_FLAGS "${SAVE_CMAKE_REQUIRED_FLAGS}") +ENDMACRO() + +FUNCTION(MY_CHECK_AND_SET_COMPILER_FLAG flag) + # At the moment this is gcc-only. + # Let's avoid expensive compiler tests on Windows: + IF(WIN32) + RETURN() + ENDIF() + MY_CHECK_C_COMPILER_FLAG(${flag}) + MY_CHECK_CXX_COMPILER_FLAG(${flag}) + STRING(REGEX REPLACE "[-,= +]" "_" result "${flag}") + FOREACH(lang C CXX) + IF (have_${lang}_${result}) + IF(ARGN) + FOREACH(type ${ARGN}) + SET(CMAKE_${lang}_FLAGS_${type} "${CMAKE_${lang}_FLAGS_${type}} ${flag}" PARENT_SCOPE) + ENDFOREACH() + ELSE() + SET(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} ${flag}" PARENT_SCOPE) + ENDIF() + ENDIF() + ENDFOREACH() +ENDFUNCTION() +