Fix possible buffer overflow

This commit is contained in:
Theo Arends 2023-07-12 12:45:02 +02:00
parent 5b6a25a7a0
commit 9638beacec

View File

@ -454,9 +454,9 @@ uint32_t SettingsConfigBackup(void) {
#endif // USE_UFILESYS #endif // USE_UFILESYS
uint32_t cfg_crc32 = Settings->cfg_crc32; uint32_t cfg_crc32 = Settings->cfg_crc32;
Settings->cfg_crc32 = GetSettingsCrc32(); // Calculate crc (again) as it might be wrong when savedata = 0 (#3918) Settings->cfg_crc32 = GetSettingsCrc32(); // Calculate crc (again) as it might be wrong when savedata = 0 (#3918)
memcpy(filebuf_ptr, Settings, sizeof(TSettings)); memcpy(filebuf_ptr, Settings, sizeof(TSettings));
Settings->cfg_crc32 = cfg_crc32; // Restore crc in case savedata = 0 to make sure settings will be noted as changed Settings->cfg_crc32 = cfg_crc32; // Restore crc in case savedata = 0 to make sure settings will be noted as changed
#ifdef USE_UFILESYS #ifdef USE_UFILESYS
if (settings_size > sizeof(TSettings)) { if (settings_size > sizeof(TSettings)) {
@ -474,13 +474,15 @@ uint32_t SettingsConfigBackup(void) {
if (XdrvCallDriver(i, FUNC_RESTORE_SETTINGS)) { // Enabled driver if (XdrvCallDriver(i, FUNC_RESTORE_SETTINGS)) { // Enabled driver
// Use most relevant config data which might not have been saved to file // Use most relevant config data which might not have been saved to file
// AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Backup driver %d"), i); // AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Backup driver %d"), i);
memcpy(filebuf_ptr, (uint8_t*)XdrvMailbox.data, fsize); uint32_t data_size = fsize; // Fix possible buffer overflow
if (data_size > XdrvMailbox.index) { data_size = XdrvMailbox.index; }
memcpy(filebuf_ptr, (uint8_t*)XdrvMailbox.data, data_size);
cfg_crc32 = GetCfgCrc32(filebuf_ptr +4, fsize -4); // Calculate crc (again) as it might be wrong when savedata = 0 (#3918) cfg_crc32 = GetCfgCrc32(filebuf_ptr +4, fsize -4); // Calculate crc (again) as it might be wrong when savedata = 0 (#3918)
filebuf_ptr[0] = cfg_crc32; filebuf_ptr[0] = cfg_crc32;
filebuf_ptr[1] = cfg_crc32 >> 8; filebuf_ptr[1] = cfg_crc32 >> 8;
filebuf_ptr[2] = cfg_crc32 >> 16; filebuf_ptr[2] = cfg_crc32 >> 16;
filebuf_ptr[3] = cfg_crc32 >> 24; filebuf_ptr[3] = cfg_crc32 >> 24;
} else { // Disabled driver } else { // Disabled driver
// As driver is not active just copy file // As driver is not active just copy file
// AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Backup file %s (%d)"), (char*)filebuf_ptr -16, fsize); // AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Backup file %s (%d)"), (char*)filebuf_ptr -16, fsize);
TfsLoadFile((const char*)filebuf_ptr -16, (uint8_t*)filebuf_ptr, fsize); TfsLoadFile((const char*)filebuf_ptr -16, (uint8_t*)filebuf_ptr, fsize);
@ -507,17 +509,17 @@ bool SettingsConfigRestore(void) {
bool valid_settings = false; bool valid_settings = false;
// unsigned long version; // 008 // unsigned long version; // 008
unsigned long buffer_version = settings_buffer[11] << 24 | settings_buffer[10] << 16 | settings_buffer[9] << 8 | settings_buffer[8]; unsigned long buffer_version = settings_buffer[11] << 24 | settings_buffer[10] << 16 | settings_buffer[9] << 8 | settings_buffer[8];
if (buffer_version > 0x06000000) { if (buffer_version > 0x06000000) {
// uint16_t cfg_size; // 002 // uint16_t cfg_size; // 002
uint32_t buffer_size = settings_buffer[3] << 8 | settings_buffer[2]; uint32_t buffer_size = settings_buffer[3] << 8 | settings_buffer[2];
if (buffer_version > 0x0606000A) { if (buffer_version > 0x0606000A) {
// uint32_t cfg_crc32; // FFC // uint32_t cfg_crc32; // FFC
uint32_t buffer_crc32 = settings_buffer[4095] << 24 | settings_buffer[4094] << 16 | settings_buffer[4093] << 8 | settings_buffer[4092]; uint32_t buffer_crc32 = settings_buffer[4095] << 24 | settings_buffer[4094] << 16 | settings_buffer[4093] << 8 | settings_buffer[4092];
valid_settings = (GetCfgCrc32(settings_buffer, buffer_size -4) == buffer_crc32); valid_settings = (GetCfgCrc32(settings_buffer, buffer_size -4) == buffer_crc32);
} else { } else {
// uint16_t cfg_crc; // 00E // uint16_t cfg_crc; // 00E
uint16_t buffer_crc16 = settings_buffer[15] << 8 | settings_buffer[14]; uint16_t buffer_crc16 = settings_buffer[15] << 8 | settings_buffer[14];
valid_settings = (GetCfgCrc16(settings_buffer, buffer_size) == buffer_crc16); valid_settings = (GetCfgCrc16(settings_buffer, buffer_size) == buffer_crc16);
} }
@ -526,7 +528,7 @@ bool SettingsConfigRestore(void) {
} }
if (valid_settings) { if (valid_settings) {
// uint8_t config_version; // F36 // uint8_t config_version; // F36
#ifdef ESP8266 #ifdef ESP8266
valid_settings = (0 == settings_buffer[0xF36]); // Settings->config_version valid_settings = (0 == settings_buffer[0xF36]); // Settings->config_version
#endif // ESP8266 #endif // ESP8266
@ -547,7 +549,7 @@ bool SettingsConfigRestore(void) {
if (valid_settings) { if (valid_settings) {
SettingsDefaultSet2(); SettingsDefaultSet2();
memcpy((char*)Settings +16, settings_buffer +16, sizeof(TSettings) -16); memcpy((char*)Settings +16, settings_buffer +16, sizeof(TSettings) -16);
Settings->version = buffer_version; // Restore version and auto upgrade after restart Settings->version = buffer_version; // Restore version and auto upgrade after restart
} }
#ifdef USE_UFILESYS #ifdef USE_UFILESYS
@ -556,25 +558,24 @@ bool SettingsConfigRestore(void) {
while ((filebuf_ptr - settings_buffer) < settings_size) { while ((filebuf_ptr - settings_buffer) < settings_size) {
uint32_t driver = atoi((const char*)filebuf_ptr +8); // /.drvset012 = 12 uint32_t driver = atoi((const char*)filebuf_ptr +8); // /.drvset012 = 12
uint32_t fsize = filebuf_ptr[15] << 8 | filebuf_ptr[14]; // Tar header settings size uint32_t fsize = filebuf_ptr[15] << 8 | filebuf_ptr[14]; // Tar header settings size
filebuf_ptr += 16; // Start of file settings filebuf_ptr += 16; // Start of file settings
uint32_t buffer_crc32 = filebuf_ptr[3] << 24 | filebuf_ptr[2] << 16 | filebuf_ptr[1] << 8 | filebuf_ptr[0]; uint32_t buffer_crc32 = filebuf_ptr[3] << 24 | filebuf_ptr[2] << 16 | filebuf_ptr[1] << 8 | filebuf_ptr[0];
bool valid_buffer = (GetCfgCrc32(filebuf_ptr +4, fsize -4) == buffer_crc32); bool valid_buffer = (GetCfgCrc32(filebuf_ptr +4, fsize -4) == buffer_crc32);
if (valid_buffer) { if (valid_buffer) {
if (XdrvCallDriver(driver, FUNC_RESTORE_SETTINGS)) { if (XdrvCallDriver(driver, FUNC_RESTORE_SETTINGS)) {
// Restore live config data which will be saved to file before restart // Restore live config data which will be saved to file before restart
// AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Restore driver %d"), driver); // AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Restore driver %d"), driver);
filebuf_ptr[1]++; // Force invalid crc32 to enable auto upgrade after restart filebuf_ptr[1]++; // Force invalid crc32 to enable auto upgrade after restart
if (fsize > XdrvMailbox.index) { uint32_t data_size = fsize; // Fix possible buffer overflow
fsize = XdrvMailbox.index; if (data_size > XdrvMailbox.index) { data_size = XdrvMailbox.index; }
} memcpy((uint8_t*)XdrvMailbox.data, filebuf_ptr, data_size); // Restore version and auto upgrade after restart
memcpy((uint8_t*)XdrvMailbox.data, filebuf_ptr, fsize); // Restore version and auto upgrade after restart
} else { } else {
// As driver is not active just copy file // As driver is not active just copy file
// AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Restore file %s (%d)"), (char*)filebuf_ptr -16, fsize); // AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Restore file %s (%d)"), (char*)filebuf_ptr -16, fsize);
TfsSaveFile((const char*)filebuf_ptr -16, (uint8_t*)filebuf_ptr, fsize); TfsSaveFile((const char*)filebuf_ptr -16, (uint8_t*)filebuf_ptr, fsize);
} }
} }
filebuf_ptr += ((fsize / 16) * 16) + 16; // Next tar header or eof filebuf_ptr += ((fsize / 16) * 16) + 16; // Next tar header or eof
} }
} }
#endif // USE_UFILESYS #endif // USE_UFILESYS