diff options
author | Nikolai Artemiev <nartemiev@google.com> | 2022-12-09 15:31:01 +1100 |
---|---|---|
committer | Edward O'Callaghan <quasisec@chromium.org> | 2022-12-23 21:40:25 +0000 |
commit | 9a152b8191c5bd3b0a88b29c6b267030da77b770 (patch) | |
tree | fb120989648ee922eb00a6d048c448bd45aec316 | |
parent | dc7485b3613c2f2752291b9b60458a27a9ac81da (diff) | |
download | flashrom-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>
-rw-r--r-- | flashrom.c | 36 |
1 files changed, 31 insertions, 5 deletions
@@ -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, ®ion); + + 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. */ |