efi_capsule_authenticate() already strips the authentication wrapper
before it verifies the signature, so on a security violation the payload
pointer and size it computed already point at the FMP payload header -
but efi_firmware_capsule_authenticate() discards them on that path and
returns. Pass them back to the caller on the violation path too.

With that in place, move the efi_firmware_get_fw_version() call in
efi_firmware_verify_image() ahead of the error check so the version is
read whether or not authentication passed. A rejected capsule then
reports its real version in ESRT rather than a stale one.

Signed-off-by: Balaji Selvanathan <[email protected]>
---
 lib/efi_loader/efi_firmware.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index 455d79a19ca..f7be480090e 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -453,6 +453,15 @@ efi_status_t efi_firmware_capsule_authenticate(const void 
**p_image,
 
                if (status == EFI_SECURITY_VIOLATION) {
                        printf("Capsule authentication check failed. Aborting 
update\n");
+                       /*
+                        * Even though authentication failed, update the 
pointers
+                        * to skip past the auth wrapper so the caller can read
+                        * the FMP payload header for version information.
+                        */
+                       image = capsule_payload;
+                       image_size = capsule_payload_size;
+                       *p_image = image;
+                       *p_image_size = image_size;
                        return status;
                } else if (status != EFI_SUCCESS) {
                        return status;
@@ -602,11 +611,10 @@ efi_status_t efi_firmware_verify_image(const void 
**p_image,
        efi_guid_t *image_type_id;
 
        ret = efi_firmware_capsule_authenticate(p_image, p_image_size);
+       efi_firmware_get_fw_version(p_image, p_image_size, state);
        if (ret != EFI_SUCCESS)
                return ret;
 
-       efi_firmware_get_fw_version(p_image, p_image_size, state);
-
        image_type_id = efi_firmware_get_image_type_id(image_index);
        if (!image_type_id)
                return EFI_INVALID_PARAMETER;

-- 
2.34.1

Reply via email to