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
