Добавлены модули SafeStack и Control Flow Integrity
This commit is contained in:
		@@ -28,7 +28,7 @@ find_package(Sanitizers)
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
You can enable the sanitizers with ``SANITIZE_ADDRESS``, ``SANITIZE_MEMORY``, ``SANITIZE_THREAD`` or ``SANITIZE_UNDEFINED`` options in your CMake configuration. You can do this by passing e.g. ``-DSANITIZE_ADDRESS=On`` on your command line or with your graphical interface.
 | 
			
		||||
You can enable the sanitizers with ``SANITIZE_ADDRESS``, ``SANITIZE_MEMORY``, ``SANITIZE_THREAD``, ``SANITIZE_UNDEFINED``, ``SANITIZE_CFI`` or ``SANITIZE_SS`` options in your CMake configuration. You can do this by passing e.g. ``-DSANITIZE_ADDRESS=On`` on your command line or with your graphical interface.
 | 
			
		||||
 | 
			
		||||
If sanitizers are supported by your compiler, the specified targets will be build with sanitizer support. If your compiler has no sanitizing capabilities (I asume intel compiler doesn't) you'll get a warning but CMake will continue processing and sanitizing will simply just be ignored.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								cmake/FindCFI.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								cmake/FindCFI.cmake
									
									
									
									
									
										Normal 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()
 | 
			
		||||
 | 
			
		||||
@@ -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
									
								
							
							
						
						
									
										24
									
								
								cmake/FindSS.cmake
									
									
									
									
									
										Normal 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()
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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 ()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user