security: Additional option for stack canaries
Previously, when stack canaries were enabled, Zephyr applied this protection to all functions. This commit introduces a new option that allows stack canary protection to be applied selectively to specific functions based on certain criteria. Signed-off-by: Flavio Ceolin <flavio.ceolin@gmail.com>
This commit is contained in:
parent
5929677d7a
commit
82ace41da4
9 changed files with 47 additions and 18 deletions
|
@ -175,6 +175,8 @@ endif()
|
||||||
# @Intent: Set compiler flags to detect general stack overflows across all functions
|
# @Intent: Set compiler flags to detect general stack overflows across all functions
|
||||||
if(CONFIG_STACK_CANARIES)
|
if(CONFIG_STACK_CANARIES)
|
||||||
zephyr_compile_options($<TARGET_PROPERTY:compiler,security_canaries>)
|
zephyr_compile_options($<TARGET_PROPERTY:compiler,security_canaries>)
|
||||||
|
elseif(CONFIG_STACK_CANARIES_STRONG)
|
||||||
|
zephyr_compile_options($<TARGET_PROPERTY:compiler,security_canaries_strong>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# @Intent: Obtain compiler optimizations flags and store in variables
|
# @Intent: Obtain compiler optimizations flags and store in variables
|
||||||
|
|
|
@ -168,6 +168,7 @@ set_compiler_property(PROPERTY imacros -imacros)
|
||||||
# Security canaries.
|
# Security canaries.
|
||||||
#no support of -mstack-protector-guard=global"
|
#no support of -mstack-protector-guard=global"
|
||||||
set_compiler_property(PROPERTY security_canaries -fstack-protector-all)
|
set_compiler_property(PROPERTY security_canaries -fstack-protector-all)
|
||||||
|
set_compiler_property(PROPERTY security_canaries_strong -fstack-protector-strong)
|
||||||
|
|
||||||
#no support of _FORTIFY_SOURCE"
|
#no support of _FORTIFY_SOURCE"
|
||||||
set_compiler_property(PROPERTY security_fortify_compile_time)
|
set_compiler_property(PROPERTY security_fortify_compile_time)
|
||||||
|
|
|
@ -92,6 +92,7 @@ set_compiler_property(PROPERTY coverage)
|
||||||
|
|
||||||
# Security canaries flags.
|
# Security canaries flags.
|
||||||
set_compiler_property(PROPERTY security_canaries)
|
set_compiler_property(PROPERTY security_canaries)
|
||||||
|
set_compiler_property(PROPERTY security_canaries_strong)
|
||||||
|
|
||||||
set_compiler_property(PROPERTY security_fortify_compile_time)
|
set_compiler_property(PROPERTY security_fortify_compile_time)
|
||||||
set_compiler_property(PROPERTY security_fortify_run_time)
|
set_compiler_property(PROPERTY security_fortify_run_time)
|
||||||
|
|
|
@ -168,12 +168,15 @@ set_compiler_property(PROPERTY coverage -fprofile-arcs -ftest-coverage -fno-inli
|
||||||
|
|
||||||
# Security canaries.
|
# Security canaries.
|
||||||
set_compiler_property(PROPERTY security_canaries -fstack-protector-all)
|
set_compiler_property(PROPERTY security_canaries -fstack-protector-all)
|
||||||
|
set_compiler_property(PROPERTY security_canaries_strong -fstack-protector-strong)
|
||||||
|
|
||||||
# Only a valid option with GCC 7.x and above, so let's do check and set.
|
# Only a valid option with GCC 7.x and above, so let's do check and set.
|
||||||
if(CONFIG_STACK_CANARIES_TLS)
|
if(CONFIG_STACK_CANARIES_TLS)
|
||||||
check_set_compiler_property(APPEND PROPERTY security_canaries -mstack-protector-guard=tls)
|
check_set_compiler_property(APPEND PROPERTY security_canaries -mstack-protector-guard=tls)
|
||||||
|
check_set_compiler_property(APPEND PROPERTY security_canaries_strong -mstack-protector-guard=tls)
|
||||||
else()
|
else()
|
||||||
check_set_compiler_property(APPEND PROPERTY security_canaries -mstack-protector-guard=global)
|
check_set_compiler_property(APPEND PROPERTY security_canaries -mstack-protector-guard=global)
|
||||||
|
check_set_compiler_property(APPEND PROPERTY security_canaries_global -mstack-protector-guard=global)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ set_target_properties(
|
||||||
__ZEPHYR_SUPERVISOR__
|
__ZEPHYR_SUPERVISOR__
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources_ifdef(CONFIG_STACK_CANARIES kernel PRIVATE compiler_stack_protect.c)
|
target_sources_ifdef(CONFIG_REQUIRES_STACK_CANARIES kernel PRIVATE compiler_stack_protect.c)
|
||||||
target_sources_ifdef(CONFIG_SYS_CLOCK_EXISTS kernel PRIVATE timeout.c timer.c)
|
target_sources_ifdef(CONFIG_SYS_CLOCK_EXISTS kernel PRIVATE timeout.c timer.c)
|
||||||
target_sources_ifdef(CONFIG_ATOMIC_OPERATIONS_C kernel PRIVATE atomic_c.c)
|
target_sources_ifdef(CONFIG_ATOMIC_OPERATIONS_C kernel PRIVATE atomic_c.c)
|
||||||
target_sources_ifdef(CONFIG_MMU kernel PRIVATE mmu.c)
|
target_sources_ifdef(CONFIG_MMU kernel PRIVATE mmu.c)
|
||||||
|
|
|
@ -869,25 +869,47 @@ config XIP
|
||||||
|
|
||||||
menu "Security Options"
|
menu "Security Options"
|
||||||
|
|
||||||
config STACK_CANARIES
|
config REQUIRES_STACK_CANARIES
|
||||||
bool "Compiler stack canaries"
|
bool
|
||||||
depends on ENTROPY_GENERATOR || TEST_RANDOM_GENERATOR
|
|
||||||
select NEED_LIBC_MEM_PARTITION if !STACK_CANARIES_TLS
|
|
||||||
help
|
help
|
||||||
This option enables compiler stack canaries.
|
Hidden option to signal that software stack protection is required.
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "Stack canaries protection options"
|
||||||
|
optional
|
||||||
|
help
|
||||||
If stack canaries are supported by the compiler, it will emit
|
If stack canaries are supported by the compiler, it will emit
|
||||||
extra code that inserts a canary value into the stack frame when
|
extra code that inserts a canary value into the stack frame when
|
||||||
a function is entered and validates this value upon exit.
|
a function is entered and validates this value upon exit.
|
||||||
Stack corruption (such as that caused by buffer overflow) results
|
Stack corruption (such as that caused by buffer overflow) results
|
||||||
in a fatal error condition for the running entity.
|
in a fatal error condition for the running entity.
|
||||||
Enabling this option can result in a significant increase
|
Enabling this option, depending on the level chosen, can result in a
|
||||||
in footprint and an associated decrease in performance.
|
significant increase in footprint and a corresponding decrease in performance.
|
||||||
|
|
||||||
If stack canaries are not supported by the compiler an error
|
If stack canaries are not supported by the compiler an error
|
||||||
will occur at build time.
|
will occur at build time.
|
||||||
|
|
||||||
if STACK_CANARIES
|
config STACK_CANARIES
|
||||||
|
bool "Maximum protection available"
|
||||||
|
depends on ENTROPY_GENERATOR || TEST_RANDOM_GENERATOR
|
||||||
|
select NEED_LIBC_MEM_PARTITION if !STACK_CANARIES_TLS
|
||||||
|
select REQUIRES_STACK_CANARIES
|
||||||
|
help
|
||||||
|
This option enables compiler stack canaries for all functions.
|
||||||
|
|
||||||
|
config STACK_CANARIES_STRONG
|
||||||
|
bool "Strong protection"
|
||||||
|
depends on ENTROPY_GENERATOR || TEST_RANDOM_GENERATOR
|
||||||
|
select NEED_LIBC_MEM_PARTITION if !STACK_CANARIES_TLS
|
||||||
|
select REQUIRES_STACK_CANARIES
|
||||||
|
help
|
||||||
|
This option enables compiler stack canaries in functions that call alloca,
|
||||||
|
functions that have local array definitiion or have references to local
|
||||||
|
frame addresses.
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
if REQUIRES_STACK_CANARIES
|
||||||
|
|
||||||
config STACK_CANARIES_TLS
|
config STACK_CANARIES_TLS
|
||||||
bool "Stack canaries using thread local storage"
|
bool "Stack canaries using thread local storage"
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* This module provides functions to support compiler stack protection
|
* This module provides functions to support compiler stack protection
|
||||||
* using canaries. This feature is enabled with configuration
|
* using canaries. This feature is enabled with configuration
|
||||||
* CONFIG_STACK_CANARIES=y.
|
* CONFIG_STACK_CANARIES=y or CONFIG_STACK_CANARIES_STRONG=y.
|
||||||
*
|
*
|
||||||
* When this feature is enabled, the compiler generated code refers to
|
* When this feature is enabled, the compiler generated code refers to
|
||||||
* function __stack_chk_fail and global variable __stack_chk_guard.
|
* function __stack_chk_fail and global variable __stack_chk_guard.
|
||||||
|
|
|
@ -289,13 +289,13 @@ void z_bss_zero_pinned(void)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_LINKER_USE_PINNED_SECTION */
|
#endif /* CONFIG_LINKER_USE_PINNED_SECTION */
|
||||||
|
|
||||||
#ifdef CONFIG_STACK_CANARIES
|
#ifdef CONFIG_REQUIRES_STACK_CANARIES
|
||||||
#ifdef CONFIG_STACK_CANARIES_TLS
|
#ifdef CONFIG_STACK_CANARIES_TLS
|
||||||
extern Z_THREAD_LOCAL volatile uintptr_t __stack_chk_guard;
|
extern Z_THREAD_LOCAL volatile uintptr_t __stack_chk_guard;
|
||||||
#else
|
#else
|
||||||
extern volatile uintptr_t __stack_chk_guard;
|
extern volatile uintptr_t __stack_chk_guard;
|
||||||
#endif /* CONFIG_STACK_CANARIES_TLS */
|
#endif /* CONFIG_STACK_CANARIES_TLS */
|
||||||
#endif /* CONFIG_STACK_CANARIES */
|
#endif /* CONFIG_REQUIRES_STACK_CANARIES */
|
||||||
|
|
||||||
/* LCOV_EXCL_STOP */
|
/* LCOV_EXCL_STOP */
|
||||||
|
|
||||||
|
@ -778,13 +778,13 @@ FUNC_NORETURN void z_cstart(void)
|
||||||
#endif
|
#endif
|
||||||
z_sys_init_run_level(INIT_LEVEL_PRE_KERNEL_2);
|
z_sys_init_run_level(INIT_LEVEL_PRE_KERNEL_2);
|
||||||
|
|
||||||
#ifdef CONFIG_STACK_CANARIES
|
#ifdef CONFIG_REQUIRES_STACK_CANARIES
|
||||||
uintptr_t stack_guard;
|
uintptr_t stack_guard;
|
||||||
|
|
||||||
z_early_rand_get((uint8_t *)&stack_guard, sizeof(stack_guard));
|
z_early_rand_get((uint8_t *)&stack_guard, sizeof(stack_guard));
|
||||||
__stack_chk_guard = stack_guard;
|
__stack_chk_guard = stack_guard;
|
||||||
__stack_chk_guard <<= 8;
|
__stack_chk_guard <<= 8;
|
||||||
#endif /* CONFIG_STACK_CANARIES */
|
#endif /* CONFIG_REQUIRES_STACK_CANARIES */
|
||||||
|
|
||||||
#ifdef CONFIG_TIMING_FUNCTIONS_NEED_AT_BOOT
|
#ifdef CONFIG_TIMING_FUNCTIONS_NEED_AT_BOOT
|
||||||
timing_init();
|
timing_init();
|
||||||
|
|
|
@ -10,13 +10,13 @@
|
||||||
#include <kernel_internal.h>
|
#include <kernel_internal.h>
|
||||||
#include <zephyr/linker/linker-defs.h>
|
#include <zephyr/linker/linker-defs.h>
|
||||||
|
|
||||||
#ifdef CONFIG_STACK_CANARIES
|
#ifdef CONFIG_REQUIRES_STACK_CANARIES
|
||||||
#ifdef CONFIG_STACK_CANARIES_TLS
|
#ifdef CONFIG_STACK_CANARIES_TLS
|
||||||
extern Z_THREAD_LOCAL volatile uintptr_t __stack_chk_guard;
|
extern Z_THREAD_LOCAL volatile uintptr_t __stack_chk_guard;
|
||||||
#else
|
#else
|
||||||
extern volatile uintptr_t __stack_chk_guard;
|
extern volatile uintptr_t __stack_chk_guard;
|
||||||
#endif /* CONFIG_STACK_CANARIES_TLS */
|
#endif /* CONFIG_STACK_CANARIES_TLS */
|
||||||
#endif /* CONFIG_STACK_CANARIES */
|
#endif /* CONFIG_REQUIRES_STACK_CANARIES */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copy the data section from ROM to RAM
|
* @brief Copy the data section from ROM to RAM
|
||||||
|
@ -49,7 +49,7 @@ void z_data_copy(void)
|
||||||
data_copy_xip_relocation();
|
data_copy_xip_relocation();
|
||||||
#endif /* CONFIG_CODE_DATA_RELOCATION */
|
#endif /* CONFIG_CODE_DATA_RELOCATION */
|
||||||
#ifdef CONFIG_USERSPACE
|
#ifdef CONFIG_USERSPACE
|
||||||
#ifdef CONFIG_STACK_CANARIES
|
#ifdef CONFIG_REQUIRES_STACK_CANARIES
|
||||||
/* stack canary checking is active for all C functions.
|
/* stack canary checking is active for all C functions.
|
||||||
* __stack_chk_guard is some uninitialized value living in the
|
* __stack_chk_guard is some uninitialized value living in the
|
||||||
* app shared memory sections. Preserve it, and don't make any
|
* app shared memory sections. Preserve it, and don't make any
|
||||||
|
@ -70,6 +70,6 @@ void z_data_copy(void)
|
||||||
#else
|
#else
|
||||||
z_early_memcpy(&_app_smem_start, &_app_smem_rom_start,
|
z_early_memcpy(&_app_smem_start, &_app_smem_rom_start,
|
||||||
_app_smem_end - _app_smem_start);
|
_app_smem_end - _app_smem_start);
|
||||||
#endif /* CONFIG_STACK_CANARIES */
|
#endif /* CONFIG_REQUIRES_STACK_CANARIES */
|
||||||
#endif /* CONFIG_USERSPACE */
|
#endif /* CONFIG_USERSPACE */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue