mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
esp32: Adds Stack Smashing Protection Feature
These changes add posibility to enable GCC stack protector via menuconfig for all source files in project.
This commit is contained in:
parent
b83792f504
commit
692a890232
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
|
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.
|
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
|
endmenu # Compiler Options
|
||||||
|
|
||||||
menu "Component config"
|
menu "Component config"
|
||||||
|
@ -10,6 +10,10 @@ PROJECT_NAME := bootloader
|
|||||||
|
|
||||||
COMPONENTS := esptool_py bootloader_support log spi_flash micro-ecc soc main
|
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.
|
#We cannot include the esp32 component directly but we need its includes.
|
||||||
CFLAGS += -I $(IDF_PATH)/components/esp32/include
|
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 $@
|
$(CC) -I ../include -C -P -x c -E $< -o $@
|
||||||
|
|
||||||
COMPONENT_EXTRA_CLEAN := esp32_out.ld
|
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 \
|
-mlongcalls \
|
||||||
-nostdlib
|
-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
|
# Optimization flags are set based on menuconfig choice
|
||||||
ifdef CONFIG_OPTIMIZATION_LEVEL_RELEASE
|
ifdef CONFIG_OPTIMIZATION_LEVEL_RELEASE
|
||||||
OPTIMIZATION_FLAGS = -Os
|
OPTIMIZATION_FLAGS = -Os
|
||||||
|
@ -21,3 +21,5 @@ CONFIG_ULP_COPROC_ENABLED=y
|
|||||||
CONFIG_TASK_WDT=n
|
CONFIG_TASK_WDT=n
|
||||||
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS=y
|
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS=y
|
||||||
CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=7
|
CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=7
|
||||||
|
CONFIG_STACK_CHECK_STRONG=y
|
||||||
|
CONFIG_STACK_CHECK=y
|
||||||
|
Loading…
Reference in New Issue
Block a user