mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
fix(esp_common/esp_fault): make ESP_FAULT_ASSERT survive optimization
ESP_FAULT_ASSERT(C) was silently deleted by the optimizer when C is a cached flag/status already proven by a preceding `if (!C) return/goto`: the compiler folds C to a constant and drops all three checks, removing the fault-injection protection with no warning.
This commit is contained in:
@@ -3,11 +3,12 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -19,6 +20,10 @@ extern "C" {
|
|||||||
* - Expands CONDITION multiple times (condition must have no side effects)
|
* - Expands CONDITION multiple times (condition must have no side effects)
|
||||||
* - Compiler is told all registers are invalid before evaluating CONDITION each time, to avoid a fault
|
* - Compiler is told all registers are invalid before evaluating CONDITION each time, to avoid a fault
|
||||||
* causing a misread of a register used in all three evaluations of CONDITION.
|
* causing a misread of a register used in all three evaluations of CONDITION.
|
||||||
|
* - The result of each evaluation is stored into a volatile variable and re-read before the branch.
|
||||||
|
* This prevents the compiler from constant-folding CONDITION and deleting the whole check when it
|
||||||
|
* has already proven the value - e.g. when this macro follows a normal "if (!cond) { ... }" check
|
||||||
|
* of the same value, which would otherwise silently remove the fault-injection protection.
|
||||||
* - If CONDITION is ever false, a system reset is triggered.
|
* - If CONDITION is ever false, a system reset is triggered.
|
||||||
*
|
*
|
||||||
* @note Place this macro after a "normal" check of CONDITION that will fail with a normal error
|
* @note Place this macro after a "normal" check of CONDITION that will fail with a normal error
|
||||||
@@ -40,13 +45,20 @@ extern "C" {
|
|||||||
* @param CONDITION A condition which will evaluate true unless an attacker used fault injection to skip or corrupt some other critical system calculation.
|
* @param CONDITION A condition which will evaluate true unless an attacker used fault injection to skip or corrupt some other critical system calculation.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define ESP_FAULT_ASSERT(CONDITION) do { \
|
#define ESP_FAULT_ASSERT(CONDITION) do { \
|
||||||
asm volatile ("" ::: "memory"); \
|
bool esp_fault_assert_chk; \
|
||||||
if(!(CONDITION)) _ESP_FAULT_RESET(); \
|
asm volatile ("" ::: "memory"); \
|
||||||
asm volatile ("" ::: "memory"); \
|
esp_fault_assert_chk = (CONDITION); \
|
||||||
if(!(CONDITION)) _ESP_FAULT_RESET(); \
|
asm volatile ("" : "+r"(esp_fault_assert_chk)); \
|
||||||
asm volatile ("" ::: "memory"); \
|
if(!esp_fault_assert_chk) _ESP_FAULT_RESET(); \
|
||||||
if(!(CONDITION)) _ESP_FAULT_RESET(); \
|
asm volatile ("" ::: "memory"); \
|
||||||
|
esp_fault_assert_chk = (CONDITION); \
|
||||||
|
asm volatile ("" : "+r"(esp_fault_assert_chk)); \
|
||||||
|
if(!esp_fault_assert_chk) _ESP_FAULT_RESET(); \
|
||||||
|
asm volatile ("" ::: "memory"); \
|
||||||
|
esp_fault_assert_chk = (CONDITION); \
|
||||||
|
asm volatile ("" : "+r"(esp_fault_assert_chk)); \
|
||||||
|
if(!esp_fault_assert_chk) _ESP_FAULT_RESET(); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ARCH_XTENSA
|
#if CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Name, Type, SubType, Offset, Size, Flags
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||||
nvs, data, nvs, 0x9000, 0x6000,
|
nvs, data, nvs, , 0x6000,
|
||||||
factory, 0, 0, 0x10000, 1M
|
factory, 0, 0, , 1M
|
||||||
flash_test, data, fat, , 528K
|
flash_test, data, fat, , 528K
|
||||||
|
|||||||
|
@@ -1,4 +1,5 @@
|
|||||||
CONFIG_ESP_TASK_WDT_EN=n
|
CONFIG_ESP_TASK_WDT_EN=n
|
||||||
|
CONFIG_PARTITION_TABLE_OFFSET=0X9000
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_SECURE_FLASH_ENC_ENABLED=y
|
CONFIG_SECURE_FLASH_ENC_ENABLED=y
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ CONFIG_EFUSE_VIRTUAL=n
|
|||||||
CONFIG_ESP32_REV_MIN_3=y
|
CONFIG_ESP32_REV_MIN_3=y
|
||||||
CONFIG_ESP32_REV_MIN=3
|
CONFIG_ESP32_REV_MIN=3
|
||||||
|
|
||||||
CONFIG_PARTITION_TABLE_OFFSET=0xD000
|
CONFIG_PARTITION_TABLE_OFFSET=0xE000
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul.csv"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user