From 62bc9bf3e59c74ea8032a3022b38edcd73efa4fa Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 26 Apr 2022 19:24:11 -0700 Subject: [PATCH] cmake: Allow selection of libc API overflow detection mode This adds a choice of three different libc API buffer overflow detection modes: * None * Compile-time * Compile-time and Run-time These correspond with the clang/gcc _FORTIFY_SOURCE modes (0/1/2). _FORTIFY_SOURCE depends on compiler optimizations and require libc support which the minimal C library doesn't include, so _FORTIFY_SOURCE is disabled by default in those cases. Native tooling might also enable _FORTIFY_SOURCE, so don't enable it by default in that case either. Signed-off-by: Keith Packard --- CMakeLists.txt | 14 +++++++-- Kconfig.zephyr | 32 ++++++++++++++++++++ cmake/compiler/arcmwdt/compiler_flags.cmake | 3 +- cmake/compiler/clang/compiler_flags.cmake | 3 +- cmake/compiler/compiler_flags_template.cmake | 3 +- cmake/compiler/gcc/compiler_flags.cmake | 3 +- 6 files changed, 52 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 59d413171aa..d31ad89ba66 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -157,8 +157,18 @@ zephyr_compile_options($<$:$:$>) # @Intent: Set compiler flags to enable buffer overflow checks in libc functions -# @config in CONFIG_NO_OPTIMIZATIONS optional : Optimizations may affect security -zephyr_compile_definitions($ ) +# @details: +# Kconfig.zephyr "Detect buffer overflows in libc calls" is a kconfig choice, +# ensuring at most *one* of CONFIG_FORTIFY_SOURCE_{COMPILE_TIME,RUN_TIME} is +# set. Refer to Kconfig.zephyr for selection logic and description of these +# choices. Toolchains set both of the security_fortify_{compile_time,run_time} +# properties and the Kconfig settings are used here to select between those. +# +if(CONFIG_FORTIFY_SOURCE_RUN_TIME) + zephyr_compile_definitions($ ) +elseif(CONFIG_FORTIFY_SOURCE_COMPILE_TIME) + zephyr_compile_definitions($ ) +endif() # @Intent: Set compiler flags to detect general stack overflows across all functions if(CONFIG_STACK_CANARIES) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 289abc2194c..e92db23d1fb 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -352,6 +352,38 @@ config COMPILER_COLOR_DIAGNOSTICS help Compiler diagnostic messages are colorized. +choice COMPILER_SECURITY_FORTIFY + prompt "Detect buffer overflows in libc calls" + default FORTIFY_SOURCE_NONE if NO_OPTIMIZATIONS || MINIMAL_LIBC || NATIVE_APPLICATION + default FORTIFY_SOURCE_COMPILE_TIME + help + Buffer overflow checking in libc calls. Supported by Clang and + GCC when using Picolibc or Newlib. Requires compiler optimization + to be enabled. + +config FORTIFY_SOURCE_NONE + bool "No detection" + help + Disables both compile-time and run-time checking. + +config FORTIFY_SOURCE_COMPILE_TIME + bool "Compile-time detection" + help + Enables only compile-time checking. Compile-time checking + doesn't increase executable size or reduce performance, it + limits checking to what can be done with information available + at compile time. + +config FORTIFY_SOURCE_RUN_TIME + bool "Compile-time and run-time detection" + help + Enables both compile-time and run-time checking. Run-time + checking increases coverage at the expense of additional code, + and means that applications will raise a runtime exception + when buffer overflow is detected. + +endchoice + config COMPILER_OPT string "Custom compiler options" help diff --git a/cmake/compiler/arcmwdt/compiler_flags.cmake b/cmake/compiler/arcmwdt/compiler_flags.cmake index 8475ad90350..3f8a98af15e 100644 --- a/cmake/compiler/arcmwdt/compiler_flags.cmake +++ b/cmake/compiler/arcmwdt/compiler_flags.cmake @@ -167,7 +167,8 @@ set_compiler_property(PROPERTY imacros -imacros) set_compiler_property(PROPERTY security_canaries -fstack-protector-all) #no support of _FORTIFY_SOURCE" -set_compiler_property(PROPERTY security_fortify "") +set_compiler_property(PROPERTY security_fortify_compile_time) +set_compiler_property(PROPERTY security_fortify_run_time) # Required C++ flags when using mwdt set_property(TARGET compiler-cpp PROPERTY required "-Hcplus" "-Hoff=Stackcheck_alloca") diff --git a/cmake/compiler/clang/compiler_flags.cmake b/cmake/compiler/clang/compiler_flags.cmake index ce0c8b17fe9..bdf00e9aaad 100644 --- a/cmake/compiler/clang/compiler_flags.cmake +++ b/cmake/compiler/clang/compiler_flags.cmake @@ -4,7 +4,8 @@ include(${ZEPHYR_BASE}/cmake/compiler/gcc/compiler_flags.cmake) # Now, let's overwrite the flags that are different in clang. # No property flag, clang doesn't understand fortify at all -set_compiler_property(PROPERTY security_fortify) +set_compiler_property(PROPERTY security_fortify_compile_time) +set_compiler_property(PROPERTY security_fortify_run_time) # No property flag, this is used by the native_posix, clang has problems # compiling the native_posix with -fno-freestanding. diff --git a/cmake/compiler/compiler_flags_template.cmake b/cmake/compiler/compiler_flags_template.cmake index 9fd4bffc364..6c020c2c475 100644 --- a/cmake/compiler/compiler_flags_template.cmake +++ b/cmake/compiler/compiler_flags_template.cmake @@ -87,7 +87,8 @@ set_compiler_property(PROPERTY coverage) # Security canaries flags. set_compiler_property(PROPERTY security_canaries) -set_compiler_property(PROPERTY security_fortify) +set_compiler_property(PROPERTY security_fortify_compile_time) +set_compiler_property(PROPERTY security_fortify_run_time) # Flag for a hosted (no-freestanding) application set_compiler_property(PROPERTY hosted) diff --git a/cmake/compiler/gcc/compiler_flags.cmake b/cmake/compiler/gcc/compiler_flags.cmake index eeeed7dfdf4..2dbb1e3e08e 100644 --- a/cmake/compiler/gcc/compiler_flags.cmake +++ b/cmake/compiler/gcc/compiler_flags.cmake @@ -157,7 +157,8 @@ 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 - set_compiler_property(PROPERTY security_fortify _FORTIFY_SOURCE=2) + set_compiler_property(PROPERTY security_fortify_compile_time _FORTIFY_SOURCE=1) + set_compiler_property(PROPERTY security_fortify_run_time _FORTIFY_SOURCE=2) endif() # gcc flag for a hosted (no-freestanding) application