From: Ana Bobillo <[email protected]>
On the capsule on disk path, efi_capsule_update_firmware() is called
without the header checks of efi_update_capsule(). It only checks
header_size against the size of the FMP capsule header, so a
header_size smaller than struct efi_capsule_header is accepted, and the
empty capsules of the FWU multi bank update are handled before any
check at all: fwu_empty_capsule_process() reads the image GUID of an
accept capsule at header_size, which may lie anywhere after the
capsule.
Check that header_size covers the capsule header and lies within the
capsule before handling any capsule, and that an accept capsule holds
the image GUID.
Fixes: 8d99026f0697 ("efi_loader: capsule: support firmware update")
Fixes: 86794052418b ("FWU: Add support for the FWU Multi Bank Update feature")
Signed-off-by: Ana Bobillo <[email protected]>
---
lib/efi_loader/efi_capsule.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index 54c118736cf..e8835315e86 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -445,7 +445,14 @@ static __maybe_unused efi_status_t
fwu_empty_capsule_process(
/*
* Image accepted by the OS. Set the acceptance
* status for the image.
+ *
+ * The caller has checked that header_size does not exceed
+ * capsule_image_size.
*/
+ if (capsule->capsule_image_size - capsule->header_size <
+ sizeof(*image_guid))
+ return EFI_INVALID_PARAMETER;
+
image_guid = (void *)(char *)capsule +
capsule->header_size;
@@ -544,6 +551,11 @@ static efi_status_t efi_capsule_update_firmware(
uint update_index;
bool fw_accept_os;
+ /* sanity check */
+ if (capsule_data->header_size < sizeof(*capsule_data) ||
+ capsule_data->header_size > capsule_data->capsule_image_size)
+ return EFI_INVALID_PARAMETER;
+
if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
if (fwu_empty_capsule(capsule_data)) {
if (fwu_empty_capsule_checks_pass()) {