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 <dnojiri@chromium.org>
Reviewed-on: https://review.coreboot.org/28886
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Daisuke Nojiri 2018-10-02 12:59:58 -07:00 committed by Martin Roth
parent 0fa007be13
commit 2b59c610d0
1 changed files with 26 additions and 35 deletions

View File

@ -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;
uint32_t next_addr = 0;
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';
/* 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;
}
if (type != CBFS_COMPONENT_NULL)
if (!next_addr)
/* Nothing to empty */
return 0;
next = cbfs_find_next_entry(image, entry);
/* We can return here if we find only a single empty entry.
For simplicity, we just proceed (and make it empty again). */
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'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, "");
addr = cbfs_get_entry_addr(image, entry);
last_addr = cbfs_get_entry_addr(
image, cbfs_find_next_entry(image, next));
// 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;
}