flash/nor/core: fix Segmentation fault during flash write of bad formed img
flash_write_unlock() sorts sections by base address but does not check if they overlap. In case of overlapped sections an item of padding[] array can get negative and padding loop writes out of allocated buffer. How to replicate: cat two copies of an ihex file to one file and try to flash it. Check for overlapped sections and abort write in such case. Change-Id: I43eee7dc290a8d18faa59567b2118b88ad4bedca Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-on: http://openocd.zylin.com/4397 Tested-by: jenkins Reviewed-by: Andreas Bolsch <hyphen0break@gmail.com>riscv-compliance-dev
parent
efe6991e80
commit
cb75947a09
|
@ -601,7 +601,7 @@ int flash_write_unlock(struct target *target, struct image *image,
|
||||||
uint32_t buffer_size;
|
uint32_t buffer_size;
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
int section_last;
|
int section_last;
|
||||||
uint32_t run_address = sections[section]->base_address + section_offset;
|
target_addr_t run_address = sections[section]->base_address + section_offset;
|
||||||
uint32_t run_size = sections[section]->size - section_offset;
|
uint32_t run_size = sections[section]->size - section_offset;
|
||||||
int pad_bytes = 0;
|
int pad_bytes = 0;
|
||||||
|
|
||||||
|
@ -617,7 +617,7 @@ int flash_write_unlock(struct target *target, struct image *image,
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
goto done;
|
goto done;
|
||||||
if (c == NULL) {
|
if (c == NULL) {
|
||||||
LOG_WARNING("no flash bank found for address %" PRIx32, run_address);
|
LOG_WARNING("no flash bank found for address " TARGET_ADDR_FMT, run_address);
|
||||||
section++; /* and skip it */
|
section++; /* and skip it */
|
||||||
section_offset = 0;
|
section_offset = 0;
|
||||||
continue;
|
continue;
|
||||||
|
@ -652,7 +652,18 @@ int flash_write_unlock(struct target *target, struct image *image,
|
||||||
/* if we have multiple sections within our image,
|
/* if we have multiple sections within our image,
|
||||||
* flash programming could fail due to alignment issues
|
* flash programming could fail due to alignment issues
|
||||||
* attempt to rebuild a consecutive buffer for the flash loader */
|
* attempt to rebuild a consecutive buffer for the flash loader */
|
||||||
pad_bytes = (sections[section_last + 1]->base_address) - (run_address + run_size);
|
target_addr_t run_next_addr = run_address + run_size;
|
||||||
|
if (sections[section_last + 1]->base_address < run_next_addr) {
|
||||||
|
LOG_ERROR("Section at " TARGET_ADDR_FMT
|
||||||
|
" overlaps section ending at " TARGET_ADDR_FMT,
|
||||||
|
sections[section_last + 1]->base_address,
|
||||||
|
run_next_addr);
|
||||||
|
LOG_ERROR("Flash write aborted.");
|
||||||
|
retval = ERROR_FAIL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
pad_bytes = sections[section_last + 1]->base_address - run_next_addr;
|
||||||
padding[section_last] = pad_bytes;
|
padding[section_last] = pad_bytes;
|
||||||
run_size += sections[++section_last]->size;
|
run_size += sections[++section_last]->size;
|
||||||
run_size += pad_bytes;
|
run_size += pad_bytes;
|
||||||
|
|
Loading…
Reference in New Issue