From 69f96f60295d82ac9525fbd20aa94a3d86c2904c Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 22 Dec 2018 00:53:14 +0100 Subject: Fix verification with sparse layouts The full verification step was not accounting for sparse layouts. Instead of the old contents, combine_image_by_layout() implicitly assumed the new contents for unspecified regions. Change-Id: I44e0cea621f2a3d4dc70fa7e93c52ed95e54014a Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/30372 Tested-by: build bot (Jenkins) --- flashrom.c | 24 +++++++++++++++--------- layout.c | 18 ++++++++++++++++++ layout.h | 1 + 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/flashrom.c b/flashrom.c index c600efc02..1a7dfb10b 100644 --- a/flashrom.c +++ b/flashrom.c @@ -2307,17 +2307,23 @@ static void combine_image_by_layout(const struct flashctx *const flashctx, uint8_t *const newcontents, const uint8_t *const oldcontents) { const struct flashrom_layout *const layout = get_layout(flashctx); + const struct romentry *included; + chipoff_t start = 0; - size_t i; - for (i = 0; i < layout->num_entries; ++i) { - if (layout->entries[i].included) - continue; - - const chipoff_t region_start = layout->entries[i].start; - const chipsize_t region_len = layout->entries[i].end - layout->entries[i].start + 1; - - memcpy(newcontents + region_start, oldcontents + region_start, region_len); + while ((included = layout_next_included_region(layout, start))) { + if (included->start > start) { + /* copy everything up to the start of this included region */ + memcpy(newcontents + start, oldcontents + start, included->start - start); + } + /* skip this included region */ + start = included->end + 1; + if (start == 0) + return; } + + /* copy the rest of the chip */ + const chipsize_t copy_len = flashctx->chip->total_size * 1024 - start; + memcpy(newcontents + start, oldcontents + start, copy_len); } /** diff --git a/layout.c b/layout.c index 9bf0b038f..cc695f0cf 100644 --- a/layout.c +++ b/layout.c @@ -225,3 +225,21 @@ int normalize_romentries(const struct flashctx *flash) return ret; } + +const struct romentry *layout_next_included_region( + const struct flashrom_layout *const l, const chipoff_t where) +{ + unsigned int i; + const struct romentry *lowest = NULL; + + for (i = 0; i < l->num_entries; ++i) { + if (!l->entries[i].included) + continue; + if (l->entries[i].end < where) + continue; + if (!lowest || lowest->start > l->entries[i].start) + lowest = &l->entries[i]; + } + + return lowest; +} diff --git a/layout.h b/layout.h index f32dc8293..7088df878 100644 --- a/layout.h +++ b/layout.h @@ -60,5 +60,6 @@ struct single_layout { struct flashrom_layout *get_global_layout(void); int process_include_args(struct flashrom_layout *); +const struct romentry *layout_next_included_region(const struct flashrom_layout *, chipoff_t); #endif /* !__LAYOUT_H__ */ -- cgit v1.2.3