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.
|
* @brief Load configuration from EEPROM and validate.
|
||||||
*
|
*
|
||||||
* Performs CRC check and sanity validation and raises the respective DTCs:
|
* On CRC failure: raise DTC_EEPROM_CFG_BAD and fall back to in-RAM defaults (no writes).
|
||||||
* - DTC_EEPROM_CFG_BAD if CRC fails
|
* On CRC OK: run sanity with autocorrect=true and raise DTC_EEPROM_CFG_SANITY with bitmask if needed.
|
||||||
* - DTC_EEPROM_CFG_SANITY with bitmask payload if values are out of bounds
|
|
||||||
*/
|
*/
|
||||||
void GetConfig_EEPROM()
|
void GetConfig_EEPROM()
|
||||||
{
|
{
|
||||||
@@ -297,12 +296,20 @@ void GetConfig_EEPROM()
|
|||||||
const uint32_t checksum = LubeConfig.checksum;
|
const uint32_t checksum = LubeConfig.checksum;
|
||||||
LubeConfig.checksum = 0;
|
LubeConfig.checksum = 0;
|
||||||
|
|
||||||
MaintainDTC(DTC_EEPROM_CFG_BAD,
|
const bool badCrc = (Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig)) != checksum);
|
||||||
(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;
|
LubeConfig.checksum = checksum;
|
||||||
|
|
||||||
const uint32_t sanity = ConfigSanityCheck(false);
|
const uint32_t sanity = ConfigSanityCheck(true);
|
||||||
MaintainDTC(DTC_EEPROM_CFG_SANITY, (sanity > 0), sanity);
|
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,
|
* If the stored start address is out of range, the persistence partition is reset,
|
||||||
* formatted, and DTC_EEPROM_PDSADRESS_BAD is raised.
|
* 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()
|
void GetPersistence_EEPROM()
|
||||||
{
|
{
|
||||||
if (!EEPROM_Available())
|
if (!EEPROM_Available())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Read wear-level start address
|
||||||
ee.readBlock(0, (uint8_t *)&globals.eePersistenceAddress, sizeof(globals.eePersistenceAddress));
|
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);
|
MovePersistencePage_EEPROM(true);
|
||||||
FormatPersistence_EEPROM();
|
FormatPersistence_EEPROM();
|
||||||
MaintainDTC(DTC_EEPROM_PDSADRESS_BAD, true);
|
MaintainDTC(DTC_EEPROM_PDSADRESS_BAD, true);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
// Safe to read the record
|
||||||
ee.readBlock(globals.eePersistenceAddress, (uint8_t *)&PersistenceData, sizeof(PersistenceData));
|
ee.readBlock(addr, (uint8_t *)&PersistenceData, sizeof(PersistenceData));
|
||||||
|
|
||||||
const uint32_t checksum = PersistenceData.checksum;
|
const uint32_t checksum = PersistenceData.checksum;
|
||||||
PersistenceData.checksum = 0;
|
PersistenceData.checksum = 0;
|
||||||
|
|
||||||
MaintainDTC(DTC_EEPROM_PDS_BAD,
|
const bool badCrc = (Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)) != checksum);
|
||||||
(Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)) != checksum));
|
MaintainDTC(DTC_EEPROM_PDS_BAD, badCrc);
|
||||||
|
|
||||||
PersistenceData.checksum = checksum;
|
if (badCrc)
|
||||||
|
{
|
||||||
|
// 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