From 2b59c610d0eda1be7774f32cf417ee7f7c60c582 Mon Sep 17 00:00:00 2001 From: Daisuke Nojiri Date: Tue, 2 Oct 2018 12:59:58 -0700 Subject: cbfstool: Clear entry being removed in all cases Currently, an entry being removed is cleared only if the next entry is also null or deleted. This patch ensures the entry being removed is cleared regardless of the next entry type. BUG=chromium:889716 BRANCH=none TEST=Run cbfstool bios.bin remove -n ecrw. Verify bios.bin has 0xFF in the space of the removed entry. TEST=Run cbfstool bios.bin remove -n fallback/payload (located at the end). Verify fallback/payload is removed. TEST=Run sign_official_build.sh on recovery_image.bin. Extract firmware contents from chromeos-firmwareupdate in the resigned image. Run 'futility vbutil_firmware --verify' for vblock_A's and FW_MAIN_A extracted from bios.bin. See the bug for details. Change-Id: I62540483da6cc35d0a604ec49b2f2b7b11ba9ce5 Signed-off-by: Daisuke Nojiri Reviewed-on: https://review.coreboot.org/28886 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- util/cbfstool/cbfs_image.c | 65 ++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 37 deletions(-) (limited to 'util') diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c index 963c892168..74572a9492 100644 --- a/util/cbfstool/cbfs_image.c +++ b/util/cbfstool/cbfs_image.c @@ -1610,47 +1610,38 @@ int cbfs_merge_empty_entry(struct cbfs_image *image, struct cbfs_file *entry, unused void *arg) { struct cbfs_file *next; - uint8_t *name; - uint32_t type, addr, last_addr; - - type = ntohl(entry->type); - if (type == CBFS_COMPONENT_DELETED) { - // Ready to be recycled. - type = CBFS_COMPONENT_NULL; - entry->type = htonl(type); - // Place NUL byte as first byte of name to be viewed as "empty". - name = (void *)&entry[1]; - *name = '\0'; - } - if (type != CBFS_COMPONENT_NULL) - return 0; + uint32_t next_addr = 0; + + /* We don't return here even if this entry is already empty because we + want to merge the empty entries following after it. */ + + /* Loop until non-empty entry is found, starting from the current entry. + After the loop, next_addr points to the next non-empty entry. */ + next = entry; + while (ntohl(next->type) == CBFS_COMPONENT_DELETED || + ntohl(next->type) == CBFS_COMPONENT_NULL) { + next = cbfs_find_next_entry(image, next); + if (!next) + break; + next_addr = cbfs_get_entry_addr(image, next); + if (!cbfs_is_valid_entry(image, next)) + /* 'next' could be the end of cbfs */ + break; + } - next = cbfs_find_next_entry(image, entry); + if (!next_addr) + /* Nothing to empty */ + return 0; - while (next && cbfs_is_valid_entry(image, next)) { - type = ntohl(next->type); - if (type == CBFS_COMPONENT_DELETED) { - type = CBFS_COMPONENT_NULL; - next->type = htonl(type); - } - if (type != CBFS_COMPONENT_NULL) - return 0; + /* We can return here if we find only a single empty entry. + For simplicity, we just proceed (and make it empty again). */ - addr = cbfs_get_entry_addr(image, entry); - last_addr = cbfs_get_entry_addr( - image, cbfs_find_next_entry(image, next)); + /* We're creating one empty entry for combined empty spaces */ + uint32_t addr = cbfs_get_entry_addr(image, entry); + size_t len = next_addr - addr - cbfs_calculate_file_header_size(""); + DEBUG("join_empty_entry: [0x%x, 0x%x) len=%zu\n", addr, next_addr, len); + cbfs_create_empty_entry(entry, CBFS_COMPONENT_NULL, len, ""); - // Now, we find two deleted/empty entries; try to merge now. - DEBUG("join_empty_entry: combine 0x%x+0x%x and 0x%x+0x%x.\n", - cbfs_get_entry_addr(image, entry), ntohl(entry->len), - cbfs_get_entry_addr(image, next), ntohl(next->len)); - cbfs_create_empty_entry(entry, CBFS_COMPONENT_NULL, - (last_addr - addr - - cbfs_calculate_file_header_size("")), - ""); - DEBUG("new empty entry: length=0x%x\n", ntohl(entry->len)); - next = cbfs_find_next_entry(image, entry); - } return 0; } -- cgit v1.2.3