Добавлены модули SafeStack и Control Flow Integrity

This commit is contained in:
2019-08-10 10:48:21 +03:00
parent 69437cd645
commit 26eced86d8
7 changed files with 78 additions and 11 deletions

31
cmake/FindCFI.cmake Normal file
View File

@ -0,0 +1,31 @@
option(SANITIZE_CFI "Enable Control Flow Integrity (CFI) for sanitized targets." OFF)
# FIXME: Might also want to add the variants of the CFI options
set(FLAG_CANDIDATES
# FIXME: Brief comment on why the additional flags
# In this case you need a
# linker that does optimization at
# linking time such as LLVM lld or GNU gold.
"-g -fsanitize=cfi -fvisibility=hidden -flto -fuse-ld=lld"
)
# There might be some conflict with the other sanitizer
# hence it might need an if statement here.
# add some handy functions
include(sanitize-helpers)
if(SANITIZE_CFI)
sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "ControlFlowIntegrity"
"CFI")
endif()
function (add_sanitize_cfi TARGET)
if (NOT SANITIZE_CFI)
return()
endif()
sanitizer_add_flags(${TARGET} "ControlFlowIntegrity" "CFI")
endfunction()

View File

@ -39,12 +39,12 @@ endif()
if (SANITIZE_MEMORY)
if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
message(WARNING "MemorySanitizer disabled for target ${TARGET} because "
message(STATUS "MemorySanitizer disabled for target ${TARGET} because "
"MemorySanitizer is supported for Linux systems only.")
set(SANITIZE_MEMORY Off CACHE BOOL
"Enable MemorySanitizer for sanitized targets." FORCE)
elseif (NOT ${CMAKE_SIZEOF_VOID_P} EQUAL 8)
message(WARNING "MemorySanitizer disabled for target ${TARGET} because "
message(STATUS "MemorySanitizer disabled for target ${TARGET} because "
"MemorySanitizer is supported for 64bit systems only.")
set(SANITIZE_MEMORY Off CACHE BOOL
"Enable MemorySanitizer for sanitized targets." FORCE)

24
cmake/FindSS.cmake Normal file
View File

@ -0,0 +1,24 @@
option(SANITIZE_SS "Enable SafeStack for sanitized targets." OFF)
set(FLAG_CANDIDATES
"-g -fsanitize=safe-stack"
)
# There might be some conflict with the other sanitizer
# hence it might need an if statement here.
# add some handy functions
include(sanitize-helpers)
if(SANITIZE_SS)
sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "SafeStack"
"SS")
endif()
function (add_sanitize_ss TARGET)
if (NOT SANITIZE_SS)
return()
endif()
sanitizer_add_flags(${TARGET} "SafeStack" "SS")
endfunction()

View File

@ -39,7 +39,8 @@ find_package(TSan ${FIND_QUIETLY_FLAG})
find_package(MSan ${FIND_QUIETLY_FLAG})
find_package(UBSan ${FIND_QUIETLY_FLAG})
find_package(LeakSan ${FIND_QUIETLY_FLAG})
find_package(CFI ${FIND_QUIETLY_FLAG})
find_package(SS ${FIND_QUIETLY_FLAG})
set(Sanitizers_COMPONENTS "")
@ -87,7 +88,8 @@ endfunction()
function(add_sanitizers ...)
# If no sanitizer is enabled, return immediately.
if (NOT (SANITIZE_ADDRESS OR SANITIZE_MEMORY OR SANITIZE_THREAD OR
SANITIZE_UNDEFINED))
SANITIZE_UNDEFINED OR SANITIZE_CFI OR SANITIZE_SS))
message(STATUS "No sanitizer selected.")
return()
endif ()
@ -96,7 +98,7 @@ function(add_sanitizers ...)
# wise sanitizers can't be used and a warning should be printed once.
get_target_property(TARGET_TYPE ${TARGET} TYPE)
if (TARGET_TYPE STREQUAL "INTERFACE_LIBRARY")
message(WARNING "Can't use any sanitizers for target ${TARGET}, "
message(STATUS "Can't use any sanitizers for target ${TARGET}, "
"because it is an interface library and cannot be "
"compiled directly.")
return()
@ -104,14 +106,14 @@ function(add_sanitizers ...)
sanitizer_target_compilers(${TARGET} TARGET_COMPILER)
list(LENGTH TARGET_COMPILER NUM_COMPILERS)
if (NUM_COMPILERS GREATER 1)
message(WARNING "Can't use any sanitizers for target ${TARGET}, "
message(STATUS "Can't use any sanitizers for target ${TARGET}, "
"because it will be compiled by incompatible compilers. "
"Target will be compiled without sanitizers.")
return()
# If the target is compiled by no or no known compiler, give a warning.
elseif (NUM_COMPILERS EQUAL 0)
message(WARNING "Sanitizers for target ${TARGET} may not be"
message(STATUS "Sanitizers for target ${TARGET} may not be"
" usable, because it uses no or an unknown compiler. "
"This is a false warning for targets using only "
"object lib(s) as input.")
@ -123,5 +125,7 @@ function(add_sanitizers ...)
add_sanitize_memory(${TARGET})
add_sanitize_undefined(${TARGET})
add_sanitize_leak(${TARGET})
add_sanitize_cfi(${TARGET})
add_sanitize_ss(${TARGET})
endforeach ()
endfunction(add_sanitizers)

View File

@ -47,12 +47,12 @@ endif()
if (SANITIZE_THREAD)
if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND
NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
message(WARNING "ThreadSanitizer disabled for target ${TARGET} because "
message(STATUS "ThreadSanitizer disabled for target ${TARGET} because "
"ThreadSanitizer is supported for Linux systems and macOS only.")
set(SANITIZE_THREAD Off CACHE BOOL
"Enable ThreadSanitizer for sanitized targets." FORCE)
elseif (NOT ${CMAKE_SIZEOF_VOID_P} EQUAL 8)
message(WARNING "ThreadSanitizer disabled for target ${TARGET} because "
message(STATUS "ThreadSanitizer disabled for target ${TARGET} because "
"ThreadSanitizer is supported for 64bit systems only.")
set(SANITIZE_THREAD Off CACHE BOOL
"Enable ThreadSanitizer for sanitized targets." FORCE)

View File

@ -121,6 +121,14 @@ function (sanitizer_check_compiler_flags FLAG_CANDIDATES NAME PREFIX)
sanitizer_check_compiler_flag("${FLAG}" ${LANG}
${PREFIX}_FLAG_DETECTED)
# Unfortunately cmake using clang is not picking up
# the CFI sanitizer flags
# CAREFUL HERE!!
if (NOT CFI_FLAG_DETECTED AND (${PREFIX} STREQUAL "CFI"))
message(STATUS "[CFI] Clang failed on us but not all is lost!!!")
set(CFI_FLAG_DETECTED TRUE)
endif()
if (${PREFIX}_FLAG_DETECTED)
# If compiler is a GNU compiler, search for static flag, if
# SANITIZE_LINK_STATIC is enabled.
@ -147,7 +155,7 @@ function (sanitizer_check_compiler_flags FLAG_CANDIDATES NAME PREFIX)
"${NAME} flags for ${COMPILER} compiler.")
mark_as_advanced(${PREFIX}_${COMPILER}_FLAGS)
message(WARNING "${NAME} is not available for ${COMPILER} "
message(STATUS "${NAME} is not available for ${COMPILER} "
"compiler. Targets using this compiler will be "
"compiled without ${NAME}.")
endif ()