diff --git a/fsw/inc/cs_eventids.h b/fsw/inc/cs_eventids.h index c85bb9f..a00248c 100644 --- a/fsw/inc/cs_eventids.h +++ b/fsw/inc/cs_eventids.h @@ -1997,6 +1997,10 @@ */ #define CS_VAL_TABLES_DEF_TBL_LONG_NAME_ERR_EID 155 +/** + * \brief CS Oneshot Checksum Failed Memory Range Validation Event ID + */ +#define CS_ONESHOT_MEMRANGE_ERR_EID 156 /**@}*/ #endif diff --git a/fsw/src/cs_cmds.c b/fsw/src/cs_cmds.c index 2434b98..3f8b80e 100644 --- a/fsw/src/cs_cmds.c +++ b/fsw/src/cs_cmds.c @@ -472,6 +472,28 @@ CFE_Status_t CS_OneShotCmd(const CS_OneShotCmd_t *CmdPtr) /* validate size and address */ Status = CFE_PSP_MemValidateRange(CmdPtr->Payload.Address, CmdPtr->Payload.Size, CFE_PSP_MEM_ANY); + if (Status == CFE_SUCCESS) + { + /* Perform application-level secondary validation */ + Status = CS_VerifyAddressRange(CmdPtr->Payload.Address, CmdPtr->Payload.Size); + + if (Status != CFE_SUCCESS) + { + CFE_EVS_SendEvent(CS_ONESHOT_MEMRANGE_ERR_EID, CFE_EVS_EventType_ERROR, + "OneShot checksum failed, address range not in a permitted memory region: 0x%08X", + (unsigned int)Status); + + CS_AppData.HkPacket.Payload.CmdErrCounter++; + } + } + else + { + CFE_EVS_SendEvent(CS_ONESHOT_MEMVALIDATE_ERR_EID, CFE_EVS_EventType_ERROR, + "OneShot checksum failed, CFE_PSP_MemValidateRange returned: 0x%08X", (unsigned int)Status); + + CS_AppData.HkPacket.Payload.CmdErrCounter++; + } + if (Status == CFE_SUCCESS) { if (CS_AppData.HkPacket.Payload.RecomputeInProgress == false && @@ -508,7 +530,7 @@ CFE_Status_t CS_OneShotCmd(const CS_OneShotCmd_t *CmdPtr) else /* child task creation failed */ { CFE_EVS_SendEvent(CS_ONESHOT_CREATE_CHDTASK_ERR_EID, CFE_EVS_EventType_ERROR, - "OneShot checkum failed, CFE_ES_CreateChildTask returned: 0x%08X", + "OneShot checksum failed, CFE_ES_CreateChildTask returned: 0x%08X", (unsigned int)Status); CS_AppData.HkPacket.Payload.CmdErrCounter++; @@ -524,13 +546,6 @@ CFE_Status_t CS_OneShotCmd(const CS_OneShotCmd_t *CmdPtr) CS_AppData.HkPacket.Payload.CmdErrCounter++; } - } /* end if CFE_PSP_MemValidateRange */ - else - { - CFE_EVS_SendEvent(CS_ONESHOT_MEMVALIDATE_ERR_EID, CFE_EVS_EventType_ERROR, - "OneShot checksum failed, CFE_PSP_MemValidateRange returned: 0x%08X", (unsigned int)Status); - - CS_AppData.HkPacket.Payload.CmdErrCounter++; } return CFE_SUCCESS; diff --git a/fsw/src/cs_utils.c b/fsw/src/cs_utils.c index 9eeb084..b48a7df 100644 --- a/fsw/src/cs_utils.c +++ b/fsw/src/cs_utils.c @@ -1148,3 +1148,82 @@ bool CS_CheckRecomputeOneshot(void) } return Result; } + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* */ +/* Verifies that an address range is safe to access */ +/* */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +CFE_Status_t CS_VerifyAddressRange(cpuaddr StartAddress, size_t Size) +{ + CFE_Status_t Status = CS_TABLE_ERROR; + CS_Res_EepromMemory_Table_Entry_t *ResultsEntry; + uint32 Loop; + + /* Check CFE core segment */ + ResultsEntry = CS_GetCfeCoreCodeSegResTable(); + if (ResultsEntry != NULL && ResultsEntry->State != CS_ChecksumState_EMPTY) + { + if (StartAddress >= ResultsEntry->StartAddress && + Size <= ResultsEntry->NumBytesToChecksum && + (StartAddress - ResultsEntry->StartAddress) <= (ResultsEntry->NumBytesToChecksum - Size)) + { + Status = CFE_SUCCESS; + } + } + + if (Status != CFE_SUCCESS) + { + /* Check OS core segment */ + ResultsEntry = CS_GetOSCodeSegResTable(); + if (ResultsEntry != NULL && ResultsEntry->State != CS_ChecksumState_EMPTY) + { + if (StartAddress >= ResultsEntry->StartAddress && + Size <= ResultsEntry->NumBytesToChecksum && + (StartAddress - ResultsEntry->StartAddress) <= (ResultsEntry->NumBytesToChecksum - Size)) + { + Status = CFE_SUCCESS; + } + } + } + + if (Status != CFE_SUCCESS) + { + /* Check Memory table */ + for (Loop = 0; Loop < CS_MAX_NUM_MEMORY_TABLE_ENTRIES; Loop++) + { + ResultsEntry = CS_GetMemoryResEntry(Loop); + if (ResultsEntry != NULL && ResultsEntry->State != CS_ChecksumState_EMPTY) + { + if (StartAddress >= ResultsEntry->StartAddress && + Size <= ResultsEntry->NumBytesToChecksum && + (StartAddress - ResultsEntry->StartAddress) <= (ResultsEntry->NumBytesToChecksum - Size)) + { + Status = CFE_SUCCESS; + break; + } + } + } + } + + if (Status != CFE_SUCCESS) + { + /* Check EEPROM table */ + for (Loop = 0; Loop < CS_MAX_NUM_EEPROM_TABLE_ENTRIES; Loop++) + { + ResultsEntry = CS_GetEepromResEntry(Loop); + if (ResultsEntry != NULL && ResultsEntry->State != CS_ChecksumState_EMPTY) + { + if (StartAddress >= ResultsEntry->StartAddress && + Size <= ResultsEntry->NumBytesToChecksum && + (StartAddress - ResultsEntry->StartAddress) <= (ResultsEntry->NumBytesToChecksum - Size)) + { + Status = CFE_SUCCESS; + break; + } + } + } + } + + return Status; +} diff --git a/fsw/src/cs_utils.h b/fsw/src/cs_utils.h index dd2d98e..a1e04cf 100644 --- a/fsw/src/cs_utils.h +++ b/fsw/src/cs_utils.h @@ -471,6 +471,11 @@ bool CS_CheckRecomputeOneshot(void); */ CS_ChecksumState_Enum_t CS_SetDefEntryState(CS_TableWrapper_t *tw, void *EntryPtr, CS_ChecksumState_Enum_t NewState); +/** + * \brief Verifies that an address range is safe to access + */ +CFE_Status_t CS_VerifyAddressRange(cpuaddr StartAddress, size_t Size); + /** * \brief Checks if the definition table matches the given name *