drivers/efi/capsules.c: fix recording capsule size

As mentioned in comments on CB:83422, size of the current data
block (which is also the last block of a capsule) was incorrectly used
in place of the capsule size:
 - when publishing a capsule in CBMEM (this worked in practice because
   CapsuleApp.efi allocates a continuous physical memory)
 - when aligning target address (which could move output pointer past
   previously allocated buffer by up to 7 bytes per capsule block)

Change-Id: I97a528e2611fcd711c555d0f01e9aadcd2031217
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/84542
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Sergii Dmytruk 2024-09-23 21:10:57 +03:00 committed by Matt DeVillier
commit 3794f9f94a

View file

@ -596,6 +596,7 @@ static void coalesce_capsules(struct block_descr block_chain, uint8_t *target)
{
struct block_descr block = block_chain;
uint8_t *capsule_start = NULL;
uint32_t capsule_size = 0;
uint32_t size_left = 0;
/* No safety checks in this function, as all of them were done earlier. */
@ -610,8 +611,10 @@ static void coalesce_capsules(struct block_descr block_chain, uint8_t *target)
if (size_left == 0) {
const EFI_CAPSULE_HEADER *capsule_hdr =
map_range(block.addr, sizeof(*capsule_hdr));
size_left = capsule_hdr->CapsuleImageSize;
capsule_size = capsule_hdr->CapsuleImageSize;
capsule_start = target;
size_left = capsule_size;
}
uint64_t addr = block.addr;
@ -641,13 +644,14 @@ static void coalesce_capsules(struct block_descr block_chain, uint8_t *target)
}
uefi_capsules[uefi_capsule_count].base = (uintptr_t)capsule_start;
uefi_capsules[uefi_capsule_count].len = block.len;
uefi_capsules[uefi_capsule_count].len = capsule_size;
uefi_capsule_count++;
/* This is to align start of the next capsule (assumes that
initial value of target was suitably aligned). */
if (!IS_ALIGNED(block.len, CAPSULE_ALIGNMENT))
target += ALIGN_UP(block.len, CAPSULE_ALIGNMENT) - block.len;
if (!IS_ALIGNED(capsule_size, CAPSULE_ALIGNMENT))
target += ALIGN_UP(capsule_size, CAPSULE_ALIGNMENT) -
capsule_size;
}
}