diff options
Diffstat (limited to 'FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c')
-rw-r--r-- | FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c | 93 |
1 files changed, 79 insertions, 14 deletions
diff --git a/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c b/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c index 5ef25d2415..b222ace6d6 100644 --- a/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c +++ b/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c @@ -13,6 +13,9 @@ #include <Library/DebugLib.h>
#include <Library/FmpDependencyLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Guid/SystemResourceTable.h>
+#include <LastAttemptStatus.h>
+#include <FmpLastAttemptStatus.h>
//
// Define the initial size of the dependency expression evaluation stack
@@ -203,6 +206,10 @@ Pop ( parameter is optional and can be set to NULL.
@param[in] FmpVersionsCount Element count of the array. When FmpVersions
is NULL, FmpVersionsCount must be 0.
+ @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the
+ last attempt status to report back to the caller.
+ This function will set the value to LAST_ATTEMPT_STATUS_SUCCESS
+ if an error code is not set.
@retval TRUE Dependency expressions evaluate to TRUE.
@retval FALSE Dependency expressions evaluate to FALSE.
@@ -211,10 +218,11 @@ Pop ( BOOLEAN
EFIAPI
EvaluateDependency (
- IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
- IN UINTN DependenciesSize,
- IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions OPTIONAL,
- IN UINTN FmpVersionsCount
+ IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
+ IN UINTN DependenciesSize,
+ IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions, OPTIONAL
+ IN UINTN FmpVersionsCount,
+ OUT UINT32 *LastAttemptStatus OPTIONAL
)
{
EFI_STATUS Status;
@@ -224,6 +232,9 @@ EvaluateDependency ( DEPEX_ELEMENT Element2;
GUID ImageTypeId;
UINT32 Version;
+ UINT32 LocalLastAttemptStatus;
+
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
//
// Check if parameter is valid.
@@ -249,6 +260,7 @@ EvaluateDependency ( case EFI_FMP_DEP_PUSH_GUID:
if (Iterator + sizeof (EFI_GUID) >= (UINT8 *) Dependencies->Dependencies + DependenciesSize) {
DEBUG ((DEBUG_ERROR, "EvaluateDependency: GUID extends beyond end of dependency expression!\n"));
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_GUID_BEYOND_DEPEX;
goto Error;
}
@@ -259,6 +271,7 @@ EvaluateDependency ( if(CompareGuid (&FmpVersions[Index].ImageTypeId, &ImageTypeId)){
Status = Push (FmpVersions[Index].Version, VersionType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
goto Error;
}
break;
@@ -266,18 +279,21 @@ EvaluateDependency ( }
if (Index == FmpVersionsCount) {
DEBUG ((DEBUG_ERROR, "EvaluateDependency: %g is not found!\n", &ImageTypeId));
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_FMP_NOT_FOUND;
goto Error;
}
break;
case EFI_FMP_DEP_PUSH_VERSION:
if (Iterator + sizeof (UINT32) >= (UINT8 *) Dependencies->Dependencies + DependenciesSize ) {
DEBUG ((DEBUG_ERROR, "EvaluateDependency: VERSION extends beyond end of dependency expression!\n"));
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_VERSION_BEYOND_DEPEX;
goto Error;
}
Version = *(UINT32 *) (Iterator + 1);
Status = Push (Version, VersionType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
goto Error;
}
Iterator = Iterator + sizeof (UINT32);
@@ -286,154 +302,191 @@ EvaluateDependency ( Iterator += AsciiStrnLenS ((CHAR8 *) Iterator, DependenciesSize - (Iterator - Dependencies->Dependencies));
if (Iterator == (UINT8 *) Dependencies->Dependencies + DependenciesSize) {
DEBUG ((DEBUG_ERROR, "EvaluateDependency: STRING extends beyond end of dependency expression!\n"));
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_VERSION_STR_BEYOND_DEPEX;
goto Error;
}
break;
case EFI_FMP_DEP_AND:
Status = Pop (&Element1, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = Pop (&Element2, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = Push (Element1.Value.Boolean & Element2.Value.Boolean, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
goto Error;
}
break;
case EFI_FMP_DEP_OR:
Status = Pop (&Element1, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = Pop(&Element2, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = Push (Element1.Value.Boolean | Element2.Value.Boolean, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
goto Error;
}
break;
case EFI_FMP_DEP_NOT:
Status = Pop (&Element1, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = Push (!(Element1.Value.Boolean), BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
goto Error;
}
break;
case EFI_FMP_DEP_TRUE:
Status = Push (TRUE, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
goto Error;
}
break;
case EFI_FMP_DEP_FALSE:
Status = Push (FALSE, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
goto Error;
}
break;
case EFI_FMP_DEP_EQ:
Status = Pop (&Element1, VersionType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = Pop (&Element2, VersionType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = (Element1.Value.Version == Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
goto Error;
}
break;
case EFI_FMP_DEP_GT:
Status = Pop (&Element1, VersionType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = Pop (&Element2, VersionType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = (Element1.Value.Version > Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
goto Error;
}
break;
case EFI_FMP_DEP_GTE:
Status = Pop (&Element1, VersionType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = Pop (&Element2, VersionType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = (Element1.Value.Version >= Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
goto Error;
}
break;
case EFI_FMP_DEP_LT:
Status = Pop (&Element1, VersionType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = Pop (&Element2, VersionType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus= LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = (Element1.Value.Version < Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
goto Error;
}
break;
case EFI_FMP_DEP_LTE:
Status = Pop (&Element1, VersionType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = Pop (&Element2, VersionType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
Status = (Element1.Value.Version <= Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_PUSH_FAILURE;
goto Error;
}
break;
case EFI_FMP_DEP_END:
Status = Pop (&Element1, BooleanType);
if (EFI_ERROR (Status)) {
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_POP_FAILURE;
goto Error;
}
return Element1.Value.Boolean;
default:
DEBUG ((DEBUG_ERROR, "EvaluateDependency: Unknown Opcode - %02x!\n", *Iterator));
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_UNKNOWN_OPCODE;
goto Error;
}
Iterator++;
}
DEBUG ((DEBUG_ERROR, "EvaluateDependency: No EFI_FMP_DEP_END Opcode in expression!\n"));
+ LocalLastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_NO_END_OPCODE;
Error:
+ if (LastAttemptStatus != NULL) {
+ *LastAttemptStatus = LocalLastAttemptStatus;
+ }
+
return FALSE;
}
/**
Validate the dependency expression and output its size.
- @param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP.
- @param[in] MaxDepexSize Max size of the dependency.
- @param[out] DepexSize Size of dependency.
+ @param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP.
+ @param[in] MaxDepexSize Max size of the dependency.
+ @param[out] DepexSize Size of dependency.
+ @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the
+ last attempt status to report back to the caller.
+ If a last attempt status error code is not returned,
+ this function will not modify the LastAttemptStatus value.
@retval TRUE The dependency expression is valid.
@retval FALSE The dependency expression is invalid.
@@ -444,7 +497,8 @@ EFIAPI ValidateDependency (
IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
IN UINTN MaxDepexSize,
- OUT UINT32 *DepexSize
+ OUT UINT32 *DepexSize,
+ OUT UINT32 *LastAttemptStatus OPTIONAL
)
{
UINT8 *Depex;
@@ -493,16 +547,23 @@ ValidateDependency ( }
}
+ if (LastAttemptStatus != NULL) {
+ *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_NO_END_OPCODE;
+ }
+
return FALSE;
}
/**
Get dependency from firmware image.
- @param[in] Image Points to the firmware image.
- @param[in] ImageSize Size, in bytes, of the firmware image.
- @param[out] DepexSize Size, in bytes, of the dependency.
-
+ @param[in] Image Points to the firmware image.
+ @param[in] ImageSize Size, in bytes, of the firmware image.
+ @param[out] DepexSize Size, in bytes, of the dependency.
+ @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the
+ last attempt status to report back to the caller.
+ If a last attempt status error code is not returned,
+ this function will not modify the LastAttemptStatus value.
@retval The pointer to dependency.
@retval Null
@@ -512,7 +573,8 @@ EFIAPI GetImageDependency (
IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image,
IN UINTN ImageSize,
- OUT UINT32 *DepexSize
+ OUT UINT32 *DepexSize,
+ OUT UINT32 *LastAttemptStatus OPTIONAL
)
{
EFI_FIRMWARE_IMAGE_DEP *Depex;
@@ -530,6 +592,9 @@ GetImageDependency ( //
// Pointer overflow. Invalid image.
//
+ if (LastAttemptStatus != NULL) {
+ *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEPENDENCY_LIB_ERROR_GET_DEPEX_FAILURE;
+ }
return NULL;
}
@@ -539,7 +604,7 @@ GetImageDependency ( //
// Validate the dependency and get the size of dependency
//
- if (ValidateDependency (Depex, MaxDepexSize, DepexSize)) {
+ if (ValidateDependency (Depex, MaxDepexSize, DepexSize, LastAttemptStatus)) {
return Depex;
}
|