From 8dd40eeeda0caba5537ec891e8f96dcb124b9487 Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Mon, 29 Apr 2024 18:32:00 +0200 Subject: [PATCH] ci(panic): add flash encrypted coredump tests --- .../system/panic/main/CMakeLists.txt | 2 +- .../system/panic/main/include/test_panic.h | 7 +++- .../system/panic/main/test_app_main.c | 4 +++ .../test_apps/system/panic/main/test_panic.c | 28 ++++++++++++++++ .../panic/partitions_coredump_encrypted.csv | 6 ++++ .../panic/partitions_coredump_plain.csv | 6 ++++ tools/test_apps/system/panic/pytest_panic.py | 33 +++++++++++++++++++ .../sdkconfig.ci.coredump_flash_encrypted | 15 +++++++++ ...ci.coredump_flash_encrypted_coredump_plain | 15 +++++++++ .../system/panic/test_panic_util/panic_dut.py | 4 +-- 10 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 tools/test_apps/system/panic/partitions_coredump_encrypted.csv create mode 100644 tools/test_apps/system/panic/partitions_coredump_plain.csv create mode 100644 tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted create mode 100644 tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted_coredump_plain diff --git a/tools/test_apps/system/panic/main/CMakeLists.txt b/tools/test_apps/system/panic/main/CMakeLists.txt index cdbffba4a4..90e5bcf973 100644 --- a/tools/test_apps/system/panic/main/CMakeLists.txt +++ b/tools/test_apps/system/panic/main/CMakeLists.txt @@ -13,7 +13,7 @@ endif() idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "include" - REQUIRES spi_flash esp_psram esp_system esp_partition + REQUIRES spi_flash esp_psram esp_system esp_partition espcoredump PRIV_REQUIRES esp_gdbstub) target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-unused-variable" diff --git a/tools/test_apps/system/panic/main/include/test_panic.h b/tools/test_apps/system/panic/main/include/test_panic.h index 64dd22a5bc..3b52370a34 100644 --- a/tools/test_apps/system/panic/main/include/test_panic.h +++ b/tools/test_apps/system/panic/main/include/test_panic.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -67,6 +67,11 @@ void test_illegal_access(void); void test_capture_dram(void); +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF +void test_setup_coredump_summary(void); +void test_coredump_summary(void); +#endif + #ifdef __cplusplus } #endif diff --git a/tools/test_apps/system/panic/main/test_app_main.c b/tools/test_apps/system/panic/main/test_app_main.c index f1da4f2fd5..6e3931b97b 100644 --- a/tools/test_apps/system/panic/main/test_app_main.c +++ b/tools/test_apps/system/panic/main/test_app_main.c @@ -116,6 +116,10 @@ void app_main(void) HANDLE_TEST(test_name, test_assert_cache_disabled); HANDLE_TEST(test_name, test_assert_cache_write_back_error_can_print_backtrace); HANDLE_TEST(test_name, test_assert_cache_write_back_error_can_print_backtrace2); +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF + HANDLE_TEST(test_name, test_setup_coredump_summary); + HANDLE_TEST(test_name, test_coredump_summary); +#endif #if CONFIG_IDF_TARGET_ESP32 HANDLE_TEST(test_name, test_illegal_access); #endif diff --git a/tools/test_apps/system/panic/main/test_panic.c b/tools/test_apps/system/panic/main/test_panic.c index 982049c07b..c2eeb8eb47 100644 --- a/tools/test_apps/system/panic/main/test_panic.c +++ b/tools/test_apps/system/panic/main/test_panic.c @@ -13,6 +13,7 @@ #include "esp_flash.h" #include "esp_system.h" #include "spi_flash_mmap.h" +#include "esp_core_dump.h" #include "esp_private/cache_utils.h" #include "esp_memory_utils.h" @@ -268,6 +269,33 @@ void test_ub(void) printf("%d\n", stuff[rand()]); } +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF +void test_setup_coredump_summary(void) +{ + if (esp_core_dump_image_erase() != ESP_OK) + die("Coredump image can not be erased!"); + assert(0); +} + +void test_coredump_summary(void) +{ + esp_core_dump_summary_t *summary = malloc(sizeof(esp_core_dump_summary_t)); + if (summary) { + esp_err_t err = esp_core_dump_get_summary(summary); + if (err == ESP_OK) { + printf("App ELF file SHA256: %s\n", (char *)summary->app_elf_sha256); + printf("Crashed task: %s\n", summary->exc_task); + char panic_reason[200]; + err = esp_core_dump_get_panic_reason(panic_reason, sizeof(panic_reason)); + if (err == ESP_OK) { + printf("Panic reason: %s\n", panic_reason); + } + } + free(summary); + } +} +#endif + /* NOTE: The following test verifies the behaviour for the * Xtensa-specific MPU instructions (Refer WDTLB, DSYNC, WDTIB, ISYNC) * used for memory protection. diff --git a/tools/test_apps/system/panic/partitions_coredump_encrypted.csv b/tools/test_apps/system/panic/partitions_coredump_encrypted.csv new file mode 100644 index 0000000000..f02bfea26f --- /dev/null +++ b/tools/test_apps/system/panic/partitions_coredump_encrypted.csv @@ -0,0 +1,6 @@ +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +nvs,data,nvs,0x11000,24K, +phy_init,data,phy,,4K, +factory,app,factory,0x20000,1M, +coredump,data,coredump,,64K,encrypted diff --git a/tools/test_apps/system/panic/partitions_coredump_plain.csv b/tools/test_apps/system/panic/partitions_coredump_plain.csv new file mode 100644 index 0000000000..d6769343d4 --- /dev/null +++ b/tools/test_apps/system/panic/partitions_coredump_plain.csv @@ -0,0 +1,6 @@ +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +nvs,data,nvs,0x11000,24K, +phy_init,data,phy,,4K, +factory,app,factory,0x20000,1M, +coredump,data,coredump,,64K, diff --git a/tools/test_apps/system/panic/pytest_panic.py b/tools/test_apps/system/panic/pytest_panic.py index b83105b76f..2242ec1bdb 100644 --- a/tools/test_apps/system/panic/pytest_panic.py +++ b/tools/test_apps/system/panic/pytest_panic.py @@ -91,6 +91,13 @@ CONFIGS_HW_STACK_GUARD_DUAL_CORE = [ CONFIG_CAPTURE_DRAM = [pytest.param('coredump_flash_capture_dram', marks=TARGETS_ALL)] +CONFIG_COREDUMP_SUMMARY = [pytest.param('coredump_flash_elf_sha', marks=TARGETS_ALL)] + +CONFIG_COREDUMP_SUMMARY_FLASH_ENCRYPTED = [ + pytest.param('coredump_flash_encrypted', marks=[pytest.mark.esp32, pytest.mark.esp32c3]), + pytest.param('coredump_flash_encrypted_coredump_plain', marks=[pytest.mark.esp32, pytest.mark.esp32c3]) +] + # Panic abort information will start with this string. PANIC_ABORT_PREFIX = 'Panic reason: ' @@ -1004,3 +1011,29 @@ def test_capture_dram(dut: PanicTestDut, config: str, test_func_name: str) -> No if dut.target != 'esp32c2': assert int(dut.gdb_data_eval_expr('g_rtc_data_var')) == 0x55AA assert int(dut.gdb_data_eval_expr('g_rtc_fast_var')) == 0xAABBCCDD + + +def _test_coredump_summary(dut: PanicTestDut, flash_encrypted: bool, coredump_encrypted: bool) -> None: + dut.run_test_func('test_setup_coredump_summary') + dut.expect_cpu_reset() + if flash_encrypted: + dut.expect_exact('Flash encryption mode is DEVELOPMENT (not secure)') + dut.run_test_func('test_coredump_summary') + if flash_encrypted and not coredump_encrypted: + dut.expect_exact('Flash encryption enabled in hardware and core dump partition is not encrypted!') + return + dut.expect_elf_sha256('App ELF file SHA256: ') + dut.expect_exact('Crashed task: main') + dut.expect(PANIC_ABORT_PREFIX + r'assert failed:[\s\w()]*?\s[.\w/]*\.(?:c|cpp|h|hpp):\d.*$') + + +@pytest.mark.generic +@pytest.mark.parametrize('config', CONFIG_COREDUMP_SUMMARY, indirect=True) +def test_coredump_summary(dut: PanicTestDut) -> None: + _test_coredump_summary(dut, False, False) + + +@pytest.mark.flash_encryption +@pytest.mark.parametrize('config', CONFIG_COREDUMP_SUMMARY_FLASH_ENCRYPTED, indirect=True) +def test_coredump_summary_flash_encrypted(dut: PanicTestDut, config: str) -> None: + _test_coredump_summary(dut, True, config == 'coredump_flash_encrypted') diff --git a/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted b/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted new file mode 100644 index 0000000000..b0f4d96191 --- /dev/null +++ b/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted @@ -0,0 +1,15 @@ +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_coredump_encrypted.csv" + +CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y +CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y +CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y + +CONFIG_SECURE_FLASH_ENC_ENABLED=y +CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y +CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=y +CONFIG_SECURE_BOOT_ALLOW_JTAG=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y +CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y diff --git a/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted_coredump_plain b/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted_coredump_plain new file mode 100644 index 0000000000..da72c14012 --- /dev/null +++ b/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted_coredump_plain @@ -0,0 +1,15 @@ +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_coredump_plain.csv" + +CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y +CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y +CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y + +CONFIG_SECURE_FLASH_ENC_ENABLED=y +CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y +CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=y +CONFIG_SECURE_BOOT_ALLOW_JTAG=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y +CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y diff --git a/tools/test_apps/system/panic/test_panic_util/panic_dut.py b/tools/test_apps/system/panic/test_panic_util/panic_dut.py index 205035e5b0..d738c307ae 100644 --- a/tools/test_apps/system/panic/test_panic_util/panic_dut.py +++ b/tools/test_apps/system/panic/test_panic_util/panic_dut.py @@ -106,13 +106,13 @@ class PanicTestDut(IdfDut): # no digital system reset for panic handling restarts (see IDF-7255) self.expect(r'.*rst:.*(RTC_SW_CPU_RST|SW_CPU_RESET|SW_CPU)') - def expect_elf_sha256(self) -> None: + def expect_elf_sha256(self, caption: str = 'ELF file SHA256: ') -> None: """Expect method for ELF SHA256 line""" elf_sha256 = sha256(self.app.elf_file) elf_sha256_len = int( self.app.sdkconfig.get('CONFIG_APP_RETRIEVE_LEN_ELF_SHA', '9') ) - self.expect_exact('ELF file SHA256: ' + elf_sha256[0:elf_sha256_len]) + self.expect_exact(caption + elf_sha256[0:elf_sha256_len]) def expect_coredump(self, output_file_name: str, patterns: List[Union[str, re.Pattern]]) -> None: with open(output_file_name, 'r') as file: