From 177fabe50c131add38d66012df09e89eaabcb9d2 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sat, 10 Sep 2022 20:16:08 +0300 Subject: [PATCH] add mpu, fix keeloq --- fbt_options.py | 4 +- firmware/targets/f7/Inc/FreeRTOSConfig.h | 6 +- firmware/targets/f7/furi_hal/furi_hal.c | 13 +-- .../targets/f7/furi_hal/furi_hal_interrupt.c | 19 ++++ firmware/targets/f7/furi_hal/furi_hal_mpu.c | 66 ++++++++++++++ .../targets/furi_hal_include/furi_hal_mpu.h | 86 +++++++++++++++++++ furi/core/memmgr.c | 6 +- lib/subghz/protocols/keeloq.c | 6 ++ 8 files changed, 188 insertions(+), 18 deletions(-) create mode 100644 firmware/targets/f7/furi_hal/furi_hal_mpu.c create mode 100644 firmware/targets/furi_hal_include/furi_hal_mpu.h diff --git a/fbt_options.py b/fbt_options.py index ab70ae8ae..c94d18da0 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -98,7 +98,7 @@ FIRMWARE_APPS = { # Svc "basic_services", # Apps - #"basic_apps", + "basic_apps", "updater_app", "storage_move_to_sd", "archive", @@ -109,7 +109,7 @@ FIRMWARE_APPS = { # Plugins #"basic_plugins", # Debug - "debug_apps", + #"debug_apps", ], } diff --git a/firmware/targets/f7/Inc/FreeRTOSConfig.h b/firmware/targets/f7/Inc/FreeRTOSConfig.h index 1df5fce78..ab2dc14ef 100644 --- a/firmware/targets/f7/Inc/FreeRTOSConfig.h +++ b/firmware/targets/f7/Inc/FreeRTOSConfig.h @@ -32,7 +32,7 @@ extern uint32_t SystemCoreClock; #define configUSE_16_BIT_TICKS 0 #define configUSE_MUTEXES 1 #define configQUEUE_REGISTRY_SIZE 0 -#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_FOR_STACK_OVERFLOW 0 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configENABLE_BACKWARD_COMPATIBILITY 0 @@ -145,3 +145,7 @@ standard names. */ #define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 1 #define configOVERRIDE_DEFAULT_TICK_CONFIGURATION \ 1 /* required only for Keil but does not hurt otherwise */ + +#define traceTASK_SWITCHED_IN() \ + extern void furi_hal_mpu_set_stack_protection(uint32_t* stack); \ + furi_hal_mpu_set_stack_protection((uint32_t*)pxCurrentTCB->pxStack) diff --git a/firmware/targets/f7/furi_hal/furi_hal.c b/firmware/targets/f7/furi_hal/furi_hal.c index dc3b1637e..662ada619 100644 --- a/firmware/targets/f7/furi_hal/furi_hal.c +++ b/firmware/targets/f7/furi_hal/furi_hal.c @@ -1,5 +1,6 @@ #include #include +#include #include @@ -36,6 +37,7 @@ void furi_hal_deinit_early() { } void furi_hal_init() { + furi_hal_mpu_init(); furi_hal_clock_init(); furi_hal_console_init(); furi_hal_rtc_init(); @@ -82,17 +84,6 @@ void furi_hal_init() { // FatFS driver initialization MX_FATFS_Init(); FURI_LOG_I(TAG, "FATFS OK"); - - // Partial null pointer dereference protection - LL_MPU_Disable(); - LL_MPU_ConfigRegion( - LL_MPU_REGION_NUMBER0, - 0x00, - 0x0, - LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO | LL_MPU_ACCESS_BUFFERABLE | - LL_MPU_ACCESS_CACHEABLE | LL_MPU_ACCESS_SHAREABLE | LL_MPU_TEX_LEVEL1 | - LL_MPU_INSTRUCTION_ACCESS_ENABLE); - LL_MPU_Enable(LL_MPU_CTRL_PRIVILEGED_DEFAULT); } void furi_hal_switch(void* address) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c index fa595921a..038ae9489 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c @@ -6,6 +6,7 @@ #include #include #include +#include #define TAG "FuriHalInterrupt" @@ -95,6 +96,10 @@ void furi_hal_interrupt_init() { LL_SYSCFG_DisableIT_FPU_IDC(); LL_SYSCFG_DisableIT_FPU_IXC(); + LL_HANDLER_EnableFault(LL_HANDLER_FAULT_USG); + LL_HANDLER_EnableFault(LL_HANDLER_FAULT_BUS); + LL_HANDLER_EnableFault(LL_HANDLER_FAULT_MEM); + FURI_LOG_I(TAG, "Init OK"); } @@ -241,6 +246,20 @@ void HardFault_Handler() { } void MemManage_Handler() { + if(FURI_BIT(SCB->CFSR, SCB_CFSR_MMARVALID_Pos)) { + uint32_t memfault_address = SCB->MMFAR; + if(memfault_address < (1024 * 1024)) { + // from 0x00 to 1MB, see FuriHalMpuRegionNULL + furi_crash("NULL pointer dereference"); + } else { + // write or read of MPU region 1 (FuriHalMpuRegionStack) + furi_crash("MPU fault, possibly stack overflow"); + } + } else if(FURI_BIT(SCB->CFSR, SCB_CFSR_MSTKERR_Pos)) { + // push to stack on MPU region 1 (FuriHalMpuRegionStack) + furi_crash("MemManage fault, possibly stack overflow"); + } + furi_crash("MemManage"); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_mpu.c b/firmware/targets/f7/furi_hal/furi_hal_mpu.c new file mode 100644 index 000000000..ea6cd55be --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_mpu.c @@ -0,0 +1,66 @@ +#include +#include + +#define FURI_HAL_MPU_ATTRIBUTES \ + (LL_MPU_ACCESS_BUFFERABLE | LL_MPU_ACCESS_CACHEABLE | LL_MPU_ACCESS_SHAREABLE | \ + LL_MPU_TEX_LEVEL1 | LL_MPU_INSTRUCTION_ACCESS_ENABLE) + +#define FURI_HAL_MPU_STACK_PROTECT_REGION FuriHalMPURegionSize32B + +void furi_hal_mpu_init() { + furi_hal_mpu_enable(); + + // NULL pointer dereference protection + furi_hal_mpu_protect_no_access(FuriHalMpuRegionNULL, 0x00, FuriHalMPURegionSize1MB); +} + +void furi_hal_mpu_enable() { + LL_MPU_Enable(LL_MPU_CTRL_PRIVILEGED_DEFAULT); +} + +void furi_hal_mpu_disable() { + LL_MPU_Disable(); +} + +void furi_hal_mpu_protect_no_access( + FuriHalMpuRegion region, + uint32_t address, + FuriHalMPURegionSize size) { + uint32_t size_ll = size; + size_ll = size_ll << MPU_RASR_SIZE_Pos; + + furi_hal_mpu_disable(); + LL_MPU_ConfigRegion( + region, 0x00, address, FURI_HAL_MPU_ATTRIBUTES | LL_MPU_REGION_NO_ACCESS | size_ll); + furi_hal_mpu_enable(); +} + +void furi_hal_mpu_protect_read_only( + FuriHalMpuRegion region, + uint32_t address, + FuriHalMPURegionSize size) { + uint32_t size_ll = size; + size_ll = size_ll << MPU_RASR_SIZE_Pos; + + furi_hal_mpu_disable(); + LL_MPU_ConfigRegion( + region, 0x00, address, FURI_HAL_MPU_ATTRIBUTES | LL_MPU_REGION_PRIV_RO_URO | size_ll); + furi_hal_mpu_enable(); +} + +void furi_hal_mpu_protect_disable(FuriHalMpuRegion region) { + furi_hal_mpu_disable(); + LL_MPU_DisableRegion(region); + furi_hal_mpu_enable(); +} + +void furi_hal_mpu_set_stack_protection(uint32_t* stack) { + // Protection area address must be aligned to region size + uint32_t stack_ptr = (uint32_t)stack; + uint32_t mask = ((1 << (FURI_HAL_MPU_STACK_PROTECT_REGION + 2)) - 1); + stack_ptr &= ~mask; + if(stack_ptr < (uint32_t)stack) stack_ptr += (mask + 1); + + furi_hal_mpu_protect_read_only( + FuriHalMpuRegionStack, stack_ptr, FURI_HAL_MPU_STACK_PROTECT_REGION); +} \ No newline at end of file diff --git a/firmware/targets/furi_hal_include/furi_hal_mpu.h b/firmware/targets/furi_hal_include/furi_hal_mpu.h new file mode 100644 index 000000000..5dddadeb6 --- /dev/null +++ b/firmware/targets/furi_hal_include/furi_hal_mpu.h @@ -0,0 +1,86 @@ +/** + * @file furi_hal_light.h + * Light control HAL API + */ + +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + FuriHalMpuRegionNULL = 0x00, // region 0 used to protect null pointer dereference + FuriHalMpuRegionStack = 0x01, // region 1 used to protect stack + FuriHalMpuRegion2 = 0x02, + FuriHalMpuRegion3 = 0x03, + FuriHalMpuRegion4 = 0x04, + FuriHalMpuRegion5 = 0x05, + FuriHalMpuRegion6 = 0x06, + FuriHalMpuRegion7 = 0x07, +} FuriHalMpuRegion; + +typedef enum { + FuriHalMPURegionSize32B = 0x04U, + FuriHalMPURegionSize64B = 0x05U, + FuriHalMPURegionSize128B = 0x06U, + FuriHalMPURegionSize256B = 0x07U, + FuriHalMPURegionSize512B = 0x08U, + FuriHalMPURegionSize1KB = 0x09U, + FuriHalMPURegionSize2KB = 0x0AU, + FuriHalMPURegionSize4KB = 0x0BU, + FuriHalMPURegionSize8KB = 0x0CU, + FuriHalMPURegionSize16KB = 0x0DU, + FuriHalMPURegionSize32KB = 0x0EU, + FuriHalMPURegionSize64KB = 0x0FU, + FuriHalMPURegionSize128KB = 0x10U, + FuriHalMPURegionSize256KB = 0x11U, + FuriHalMPURegionSize512KB = 0x12U, + FuriHalMPURegionSize1MB = 0x13U, + FuriHalMPURegionSize2MB = 0x14U, + FuriHalMPURegionSize4MB = 0x15U, + FuriHalMPURegionSize8MB = 0x16U, + FuriHalMPURegionSize16MB = 0x17U, + FuriHalMPURegionSize32MB = 0x18U, + FuriHalMPURegionSize64MB = 0x19U, + FuriHalMPURegionSize128MB = 0x1AU, + FuriHalMPURegionSize256MB = 0x1BU, + FuriHalMPURegionSize512MB = 0x1CU, + FuriHalMPURegionSize1GB = 0x1DU, + FuriHalMPURegionSize2GB = 0x1EU, + FuriHalMPURegionSize4GB = 0x1FU, +} FuriHalMPURegionSize; + +/** + * @brief Initialize memory protection unit + */ +void furi_hal_mpu_init(); + +/** +* @brief Enable memory protection unit +*/ +void furi_hal_mpu_enable(); + +/** +* @brief Disable memory protection unit +*/ +void furi_hal_mpu_disable(); + +void furi_hal_mpu_protect_no_access( + FuriHalMpuRegion region, + uint32_t address, + FuriHalMPURegionSize size); + +void furi_hal_mpu_protect_read_only( + FuriHalMpuRegion region, + uint32_t address, + FuriHalMPURegionSize size); + +void furi_hal_mpu_protect_disable(FuriHalMpuRegion region); + +#ifdef __cplusplus +} +#endif diff --git a/furi/core/memmgr.c b/furi/core/memmgr.c index 6bad14027..dba1a7074 100644 --- a/furi/core/memmgr.c +++ b/furi/core/memmgr.c @@ -37,10 +37,8 @@ void* calloc(size_t count, size_t size) { } char* strdup(const char* s) { - const char* s_null = s; - if(s_null == NULL) { - return NULL; - } + // arg s marked as non-null, so we need hack to check for NULL + furi_check(((uint32_t)s << 2) != 0); size_t siz = strlen(s) + 1; char* y = pvPortMalloc(siz); diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index a0953b1df..ab1626a6f 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -140,6 +140,9 @@ static bool subghz_protocol_keeloq_gen_data(SubGhzProtocolEncoderKeeloq* instanc uint64_t man = 0; uint64_t code_found_reverse; int res = 0; + if(instance->manufacture_name == 0x0) { + instance->manufacture_name = ""; + } if(strcmp(instance->manufacture_name, "Unknown") == 0) { code_found_reverse = subghz_protocol_blocks_reverse_key( @@ -559,6 +562,9 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( uint32_t decrypt = 0; uint64_t man; int res = 0; + if(mfname == 0x0) { + mfname = ""; + } if(strcmp(mfname, "") == 0) { for