From 01592071f1e205e7a020d9dd487c04943226c287 Mon Sep 17 00:00:00 2001 From: Mark Ruvald Pedersen Date: Thu, 10 Jan 2019 12:07:51 +0100 Subject: [PATCH] cmake: Toolchain abstraction: security Introduce the first of the toolchain_cc-family of macros: toolchain_cc_security_fortify and toolchain_cc_security_canaries. No functional change expected. Fortify source is not supported by Clang, but this commit retains current behavior. This is motivated by the wish to abstract Zephyr's usage of toolchains, permitting easier porting to other (commercial) toolchains. Signed-off-by: Mark Ruvald Pedersen --- CMakeLists.txt | 18 +++++++----------- cmake/compiler/clang/target.cmake | 5 +++++ cmake/compiler/gcc/target.cmake | 4 ++++ .../gcc/target_security_canaries.cmake | 9 +++++++++ .../compiler/gcc/target_security_fortify.cmake | 13 +++++++++++++ cmake/compiler/host-gcc/target.cmake | 5 +++++ 6 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 cmake/compiler/gcc/target_security_canaries.cmake create mode 100644 cmake/compiler/gcc/target_security_fortify.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 20a7559c713..0eaa3feb3e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,10 +75,13 @@ zephyr_compile_definitions( __ZEPHYR__=1 ) -if(NOT CONFIG_NO_OPTIMIZATIONS) -zephyr_compile_definitions( - _FORTIFY_SOURCE=2 -) +# @Intent: Set compiler flags to enable buffer overflow checks in libc functions +# @config in CONFIG_NO_OPTIMIZATIONS optional : Optimizations may affect security +toolchain_cc_security_fortify() + +# @Intent: Set compiler flags to detect general stack overflows across all functions +if(CONFIG_STACK_CANARIES) + toolchain_cc_security_canaries() endif() if(BUILD_VERSION) @@ -269,13 +272,6 @@ zephyr_cc_option(-fno-pic) zephyr_cc_option(-fno-strict-overflow) zephyr_cc_option(-Wno-pointer-sign) -if(CONFIG_STACK_CANARIES) - zephyr_compile_options(-fstack-protector-all) - - # Only a valid option with GCC 7.x and above - zephyr_cc_option(-mstack-protector-guard=global) -endif() - if(CONFIG_OVERRIDE_FRAME_POINTER_DEFAULT) if(CONFIG_OMIT_FRAME_POINTER) zephyr_cc_option(-fomit-frame-pointer) diff --git a/cmake/compiler/clang/target.cmake b/cmake/compiler/clang/target.cmake index db7e85a1795..f12abf22f42 100644 --- a/cmake/compiler/clang/target.cmake +++ b/cmake/compiler/clang/target.cmake @@ -51,3 +51,8 @@ list(APPEND TOOLCHAIN_LIBS gcc) set(CMAKE_REQUIRED_FLAGS -nostartfiles -nostdlib ${isystem_include_flags} -Wl,--unresolved-symbols=ignore-in-object-files) string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + +# Load toolchain_cc-family macros +# Clang and GCC are almost feature+flag compatible, so reuse freestanding gcc +include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_fortify.cmake) +include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_canaries.cmake) diff --git a/cmake/compiler/gcc/target.cmake b/cmake/compiler/gcc/target.cmake index afbdaa118e7..096a83199e7 100644 --- a/cmake/compiler/gcc/target.cmake +++ b/cmake/compiler/gcc/target.cmake @@ -160,3 +160,7 @@ endforeach() # toolchain-specific flags at generation time. list(APPEND CMAKE_REQUIRED_FLAGS -nostartfiles -nostdlib ${isystem_include_flags} -Wl,--unresolved-symbols=ignore-in-object-files) string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + +# Load toolchain_cc-family macros +include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_security_fortify.cmake) +include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_security_canaries.cmake) diff --git a/cmake/compiler/gcc/target_security_canaries.cmake b/cmake/compiler/gcc/target_security_canaries.cmake new file mode 100644 index 00000000000..5979fc2e873 --- /dev/null +++ b/cmake/compiler/gcc/target_security_canaries.cmake @@ -0,0 +1,9 @@ +# See root CMakeLists.txt for description and expectations of this macro +macro(toolchain_cc_security_canaries) + + zephyr_compile_options(-fstack-protector-all) + + # Only a valid option with GCC 7.x and above + zephyr_cc_option(-mstack-protector-guard=global) + +endmacro() diff --git a/cmake/compiler/gcc/target_security_fortify.cmake b/cmake/compiler/gcc/target_security_fortify.cmake new file mode 100644 index 00000000000..ec682b47fe3 --- /dev/null +++ b/cmake/compiler/gcc/target_security_fortify.cmake @@ -0,0 +1,13 @@ +# See root CMakeLists.txt for description and expectations of this macro +macro(toolchain_cc_security_fortify) + + if(NOT CONFIG_NO_OPTIMIZATIONS) + # _FORTIFY_SOURCE: Detect common-case buffer overflows for certain functions + # _FORTIFY_SOURCE=1 : Compile-time checks (requires -O1 at least) + # _FORTIFY_SOURCE=2 : Additional lightweight run-time checks + zephyr_compile_definitions( + _FORTIFY_SOURCE=2 + ) + endif() + +endmacro() diff --git a/cmake/compiler/host-gcc/target.cmake b/cmake/compiler/host-gcc/target.cmake index 88da79a11a2..49ca6c3ed0a 100644 --- a/cmake/compiler/host-gcc/target.cmake +++ b/cmake/compiler/host-gcc/target.cmake @@ -41,3 +41,8 @@ assert_exists(LIBGCC_FILE_NAME) # "/usr/lib/gcc/x86_64-linux-gnu/7/IAMCU/libgcc.a" are unheard of. # So this does not support CONFIG_X86_IAMCU=y LIST(APPEND TOOLCHAIN_LIBS gcc) + +# Load toolchain_cc-family macros +# Significant overlap with freestanding gcc compiler so reuse it +include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_fortify.cmake) +include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_canaries.cmake)