summaryrefslogtreecommitdiffstats
path: root/flashrom.c
diff options
context:
space:
mode:
authorNikolai Artemiev <nartemiev@google.com>2022-12-09 15:31:01 +1100
committerEdward O'Callaghan <quasisec@chromium.org>2022-12-23 21:40:25 +0000
commit9a152b8191c5bd3b0a88b29c6b267030da77b770 (patch)
treefb120989648ee922eb00a6d048c448bd45aec316 /flashrom.c
parentdc7485b3613c2f2752291b9b60458a27a9ac81da (diff)
downloadflashrom-9a152b8191c5bd3b0a88b29c6b267030da77b770.tar.gz
flashrom-9a152b8191c5bd3b0a88b29c6b267030da77b770.tar.bz2
flashrom-9a152b8191c5bd3b0a88b29c6b267030da77b770.zip
flashrom: Check for flash access restrictions in erase path
Skip unwritable regions if FLASHROM_FLAG_SKIP_UNWRITABLE_REGIONS is true. If the flag is false, erase operations that include an unwritable region will not erase anything and return an error. BUG=b:260440773 BRANCH=none TEST=flashrom -E on dedede (JSL) Change-Id: If027a96a024782c7707c6d38680709a1a117f3ef CoAuthored-by: Edward O'Callaghan <quasisec@google.com> Signed-off-by: Edward O'Callaghan <quasisec@google.com> Signed-off-by: Nikolai Artemiev <nartemiev@google.com> Reviewed-on: https://review.coreboot.org/c/flashrom/+/70517 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Edward O'Callaghan <quasisec@chromium.org> Reviewed-by: Felix Singer <felixsinger@posteo.net>
Diffstat (limited to 'flashrom.c')
-rw-r--r--flashrom.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/flashrom.c b/flashrom.c
index b611bebc1..62f38f80f 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -1460,13 +1460,39 @@ static int erase_block(struct flashctx *const flashctx,
all_skipped = false;
msg_cdbg("E");
- if (erasefn(flashctx, info->erase_start, erase_len))
- goto _free_ret;
- if (check_erased_range(flashctx, info->erase_start, erase_len)) {
- msg_cerr("ERASE FAILED!\n");
- goto _free_ret;
+
+ if (!flashctx->flags.skip_unwritable_regions) {
+ if (check_for_unwritable_regions(flashctx, info->erase_start, erase_len))
+ goto _free_ret;
+ }
+
+ unsigned int len;
+ for (unsigned int addr = info->erase_start; addr < info->erase_start + erase_len; addr += len) {
+ struct flash_region region;
+ get_flash_region(flashctx, addr, &region);
+
+ len = min(info->erase_start + erase_len, region.end) - addr;
+
+ if (region.write_prot) {
+ msg_gdbg("%s: cannot erase inside %s region (%#08x..%#08x), skipping range (%#08x..%#08x).\n",
+ __func__, region.name, region.start, region.end - 1, addr, addr + len - 1);
+ free(region.name);
+ continue;
+ }
+
+ msg_gdbg("%s: %s region (%#08x..%#08x) is writable, erasing range (%#08x..%#08x).\n",
+ __func__, region.name, region.start, region.end - 1, addr, addr + len - 1);
+ free(region.name);
+
+ if (erasefn(flashctx, addr, len))
+ goto _free_ret;
+ if (check_erased_range(flashctx, addr, len)) {
+ msg_cerr("ERASE FAILED!\n");
+ goto _free_ret;
+ }
}
+
if (region_unaligned) {
unsigned int starthere = 0, lenhere = 0, writecount = 0;
/* get_next_write() sets starthere to a new value after the call. */