Merge branch 'feature/esp32_stack_protector' into 'master'
esp32: Adds Stack Smashing Protection Feature See merge request !1537
This commit is contained in:
commit
148130066f
8 changed files with 147 additions and 0 deletions
35
Kconfig
35
Kconfig
|
@ -105,6 +105,41 @@ config CXX_EXCEPTIONS
|
|||
Enabling this option currently adds an additional 20KB of heap overhead, and 4KB of additional heap is allocated
|
||||
the first time an exception is thrown in user code.
|
||||
|
||||
choice STACK_CHECK_MODE
|
||||
prompt "Stack smashing protection mode"
|
||||
default STACK_CHECK_NONE
|
||||
help
|
||||
Stack smashing protection mode. Emit extra code to check for buffer overflows, such as stack
|
||||
smashing attacks. This is done by adding a guard variable to functions with vulnerable objects.
|
||||
The guards are initialized when a function is entered and then checked when the function exits.
|
||||
If a guard check fails, program is halted. Protection has the following modes:
|
||||
- In NORMAL mode (GCC flag: -fstack-protector) only functions that call alloca, and functions with buffers larger than
|
||||
8 bytes are protected.
|
||||
- STRONG mode (GCC flag: -fstack-protector-strong) is like NORMAL, but includes additional functions to be protected -- those that
|
||||
have local array definitions, or have references to local frame addresses.
|
||||
- In OVERALL mode (GCC flag: -fstack-protector-all) all functions are protected.
|
||||
|
||||
Modes have the following impact on code performance and coverage:
|
||||
- performance: NORMAL > STRONG > OVERALL
|
||||
- coverage: NORMAL < STRONG < OVERALL
|
||||
|
||||
|
||||
config STACK_CHECK_NONE
|
||||
bool "None"
|
||||
config STACK_CHECK_NORM
|
||||
bool "Normal"
|
||||
config STACK_CHECK_STRONG
|
||||
bool "Strong"
|
||||
config STACK_CHECK_ALL
|
||||
bool "Overall"
|
||||
endchoice
|
||||
|
||||
config STACK_CHECK
|
||||
bool
|
||||
default !STACK_CHECK_NONE
|
||||
help
|
||||
Stack smashing protection.
|
||||
|
||||
endmenu # Compiler Options
|
||||
|
||||
menu "Component config"
|
||||
|
|
|
@ -10,6 +10,10 @@ PROJECT_NAME := bootloader
|
|||
|
||||
COMPONENTS := esptool_py bootloader_support log spi_flash micro-ecc soc main
|
||||
|
||||
# Clear C and CXX from top level project
|
||||
CFLAGS =
|
||||
CXXFLAGS =
|
||||
|
||||
#We cannot include the esp32 component directly but we need its includes.
|
||||
CFLAGS += -I $(IDF_PATH)/components/esp32/include
|
||||
|
||||
|
|
|
@ -61,3 +61,7 @@ esp32_out.ld: $(COMPONENT_PATH)/ld/esp32.ld ../include/sdkconfig.h
|
|||
$(CC) -I ../include -C -P -x c -E $< -o $@
|
||||
|
||||
COMPONENT_EXTRA_CLEAN := esp32_out.ld
|
||||
|
||||
# disable stack protection in files which are involved in initialization of that feature
|
||||
stack_check.o: CFLAGS := $(filter-out -fstack-protector%, $(CFLAGS))
|
||||
cpu_start.o: CFLAGS := $(filter-out -fstack-protector%, $(CFLAGS))
|
39
components/esp32/stack_check.c
Normal file
39
components/esp32/stack_check.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
#if CONFIG_STACK_CHECK
|
||||
|
||||
#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "stack_chk";
|
||||
|
||||
void *__stack_chk_guard = NULL;
|
||||
|
||||
static void __attribute__ ((constructor))
|
||||
__esp_stack_guard_setup (void)
|
||||
{
|
||||
ESP_LOGD(TAG, "Intialize random stack guard");
|
||||
__stack_chk_guard = (void *)esp_random();
|
||||
}
|
||||
|
||||
void __stack_chk_fail (void)
|
||||
{
|
||||
ets_printf("\r\nStack smashing protect failure!\r\n\r\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
#endif
|
25
components/esp32/test/test_stack_check.c
Normal file
25
components/esp32/test/test_stack_check.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include "unity.h"
|
||||
|
||||
#if CONFIG_STACK_CHECK
|
||||
|
||||
static void recur_and_smash()
|
||||
{
|
||||
static int cnt;
|
||||
volatile uint8_t buf[50];
|
||||
volatile int num = sizeof(buf)+10;
|
||||
|
||||
if (cnt++ < 1) {
|
||||
recur_and_smash();
|
||||
}
|
||||
for (int i = 0; i < num; i++) {
|
||||
buf[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("stack smashing protection", "[stack_check] [ignore]")
|
||||
{
|
||||
recur_and_smash();
|
||||
}
|
||||
|
||||
#endif
|
25
components/esp32/test/test_stack_check_cxx.cpp
Normal file
25
components/esp32/test/test_stack_check_cxx.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include "unity.h"
|
||||
|
||||
#if CONFIG_STACK_CHECK
|
||||
|
||||
static void recur_and_smash_cxx()
|
||||
{
|
||||
static int cnt;
|
||||
volatile uint8_t buf[50];
|
||||
volatile int num = sizeof(buf)+10;
|
||||
|
||||
if (cnt++ < 1) {
|
||||
recur_and_smash_cxx();
|
||||
}
|
||||
for (int i = 0; i < num; i++) {
|
||||
buf[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("stack smashing protection CXX", "[stack_check] [ignore]")
|
||||
{
|
||||
recur_and_smash_cxx();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -264,6 +264,19 @@ COMMON_FLAGS = \
|
|||
-mlongcalls \
|
||||
-nostdlib
|
||||
|
||||
ifndef IS_BOOTLOADER_BUILD
|
||||
# stack protection (only one option can be selected in menuconfig)
|
||||
ifdef CONFIG_STACK_CHECK_NORM
|
||||
COMMON_FLAGS += -fstack-protector
|
||||
endif
|
||||
ifdef CONFIG_STACK_CHECK_STRONG
|
||||
COMMON_FLAGS += -fstack-protector-strong
|
||||
endif
|
||||
ifdef CONFIG_STACK_CHECK_ALL
|
||||
COMMON_FLAGS += -fstack-protector-all
|
||||
endif
|
||||
endif
|
||||
|
||||
# Optimization flags are set based on menuconfig choice
|
||||
ifdef CONFIG_OPTIMIZATION_LEVEL_RELEASE
|
||||
OPTIMIZATION_FLAGS = -Os
|
||||
|
|
|
@ -21,3 +21,5 @@ CONFIG_ULP_COPROC_ENABLED=y
|
|||
CONFIG_TASK_WDT=n
|
||||
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS=y
|
||||
CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=7
|
||||
CONFIG_STACK_CHECK_STRONG=y
|
||||
CONFIG_STACK_CHECK=y
|
||||
|
|
Loading…
Reference in a new issue