Hi,

Trying to report a bug in flashrom 1.4. I'm not subject matter expert, but I've 
done my best to try and debug and fix the issue. Seeking guidance from the 
experts on whether this is the solution :-)

I found that in 1.4, it looks like the erase and write logic was refactored. 
Since then, I get segfaults when trying to flash my coreboot image.

The chip is a Macronix MX25U6435E in a Protectli FW4B. I'm running on OpenBSD 
7.5.

The segfault occurs in erasure_layout.c: init_eraseblock line 55. I am no 
expert on the internals of flashrom, or what's going on here...but I've 
narrowed it down to segfaulting at the last iteration of this while loop. Code 
in question looks like:

edata->first_sub_block_index = *sub_block_index;
struct eraseblock_data *subedata = &layout[idx - 
1].layout_list[*sub_block_index];
while (subedata->start_addr >= start_addr && subedata->end_addr <= end_addr &&
        *sub_block_index < layout[idx-1].block_count) {
        (*sub_block_index)++;
        subedata++;
}

In my case, it seems that the last iteration looks like:

layout[idx-1].block_count == 2048
*sub_block_index == 2047
subedata->end_addr == end_addr

What then happens is, the variable "subedata" is incremented and the while 
condition is checked, but subedata is now out of bounds and the application 
segfaults. I'm pretty sure the while loop shouldn't iterate again because the 
next iteration would fail the *sub_block_index < layout[idx-1].block_count 
check (2048 < 2028). I solved this by short circuiting the while condition and 
checking that condition first, so that subedata is not accessed and flashrom 
successfully flashes my coreboot image. Patch included below. Is this an 
appropriate fix?

Thank you,

Grant

--- erasure_layout.c.orig
+++ erasure_layout.c
@@ -52,8 +52,8 @@
 
        edata->first_sub_block_index = *sub_block_index;
        struct eraseblock_data *subedata = &layout[idx - 
1].layout_list[*sub_block_index];
-       while (subedata->start_addr >= start_addr && subedata->end_addr <= 
end_addr &&
-               *sub_block_index < layout[idx-1].block_count) {
+       while (*sub_block_index < layout[idx-1].block_count &&
+               subedata->start_addr >= start_addr && subedata->end_addr <= 
end_addr) {
                (*sub_block_index)++;
                subedata++;
        }
_______________________________________________
flashrom mailing list -- flashrom@flashrom.org
To unsubscribe send an email to flashrom-le...@flashrom.org

Reply via email to