hardened EEPROM against out of Bounds and garbage in RAM
This commit is contained in:
@@ -283,9 +283,8 @@ void StoreConfig_EEPROM()
|
||||
/**
|
||||
* @brief Load configuration from EEPROM and validate.
|
||||
*
|
||||
* Performs CRC check and sanity validation and raises the respective DTCs:
|
||||
* - DTC_EEPROM_CFG_BAD if CRC fails
|
||||
* - DTC_EEPROM_CFG_SANITY with bitmask payload if values are out of bounds
|
||||
* On CRC failure: raise DTC_EEPROM_CFG_BAD and fall back to in-RAM defaults (no writes).
|
||||
* On CRC OK: run sanity with autocorrect=true and raise DTC_EEPROM_CFG_SANITY with bitmask if needed.
|
||||
*/
|
||||
void GetConfig_EEPROM()
|
||||
{
|
||||
@@ -297,12 +296,20 @@ void GetConfig_EEPROM()
|
||||
const uint32_t checksum = LubeConfig.checksum;
|
||||
LubeConfig.checksum = 0;
|
||||
|
||||
MaintainDTC(DTC_EEPROM_CFG_BAD,
|
||||
(Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig)) != checksum));
|
||||
const bool badCrc = (Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig)) != checksum);
|
||||
MaintainDTC(DTC_EEPROM_CFG_BAD, badCrc);
|
||||
|
||||
if (badCrc) {
|
||||
// Don’t keep corrupted data in RAM
|
||||
LubeConfig = LubeConfig_defaults;
|
||||
LubeConfig.EEPROM_Version = EEPROM_STRUCTURE_REVISION; // explicit in-RAM version
|
||||
return;
|
||||
}
|
||||
|
||||
// CRC OK → restore checksum and sanitize (with autocorrect)
|
||||
LubeConfig.checksum = checksum;
|
||||
|
||||
const uint32_t sanity = ConfigSanityCheck(false);
|
||||
const uint32_t sanity = ConfigSanityCheck(true);
|
||||
MaintainDTC(DTC_EEPROM_CFG_SANITY, (sanity > 0), sanity);
|
||||
}
|
||||
|
||||
@@ -333,33 +340,48 @@ void StorePersistence_EEPROM()
|
||||
*
|
||||
* If the stored start address is out of range, the persistence partition is reset,
|
||||
* formatted, and DTC_EEPROM_PDSADRESS_BAD is raised.
|
||||
* Otherwise, the record is read and checked; DTC_EEPROM_PDS_BAD is raised on CRC failure.
|
||||
* Otherwise, the record is read and checked; on CRC failure DTC_EEPROM_PDS_BAD is raised
|
||||
* and the in-RAM persistence data is reset to a safe default (no writes performed here).
|
||||
*/
|
||||
void GetPersistence_EEPROM()
|
||||
{
|
||||
if (!EEPROM_Available())
|
||||
return;
|
||||
|
||||
// Read wear-level start address
|
||||
ee.readBlock(0, (uint8_t *)&globals.eePersistenceAddress, sizeof(globals.eePersistenceAddress));
|
||||
|
||||
if (globals.eePersistenceAddress < startofPersistence || globals.eePersistenceAddress > ee.getDeviceSize())
|
||||
const uint16_t addr = globals.eePersistenceAddress;
|
||||
const uint16_t need = sizeof(PersistenceData);
|
||||
const uint16_t dev = ee.getDeviceSize();
|
||||
|
||||
// Strict range check: addr must be within partition and block must fit into device
|
||||
if (addr < startofPersistence || (uint32_t)addr + (uint32_t)need > (uint32_t)dev)
|
||||
{
|
||||
MovePersistencePage_EEPROM(true);
|
||||
FormatPersistence_EEPROM();
|
||||
MaintainDTC(DTC_EEPROM_PDSADRESS_BAD, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
// Safe to read the record
|
||||
ee.readBlock(addr, (uint8_t *)&PersistenceData, sizeof(PersistenceData));
|
||||
|
||||
const uint32_t checksum = PersistenceData.checksum;
|
||||
PersistenceData.checksum = 0;
|
||||
|
||||
const bool badCrc = (Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)) != checksum);
|
||||
MaintainDTC(DTC_EEPROM_PDS_BAD, badCrc);
|
||||
|
||||
if (badCrc)
|
||||
{
|
||||
ee.readBlock(globals.eePersistenceAddress, (uint8_t *)&PersistenceData, sizeof(PersistenceData));
|
||||
|
||||
const uint32_t checksum = PersistenceData.checksum;
|
||||
PersistenceData.checksum = 0;
|
||||
|
||||
MaintainDTC(DTC_EEPROM_PDS_BAD,
|
||||
(Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)) != checksum));
|
||||
|
||||
PersistenceData.checksum = checksum;
|
||||
// Do not keep corrupted data in RAM; leave DTC set, no EEPROM writes here
|
||||
PersistenceData = {0};
|
||||
return;
|
||||
}
|
||||
|
||||
// CRC ok -> restore checksum into the struct kept in RAM
|
||||
PersistenceData.checksum = checksum;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user