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()) {

Reply via email to