From nobody Tue Apr 16 13:31:03 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+59603+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+59603+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1589493169; cv=none; d=zohomail.com; s=zohoarc; b=ETmo19wgy6lVnXw85Pzj0GmU0i925R8wBC2tA8yGT2f3iTl48ZNA5b34IrGgO6xdPf5mSuZUF3fp4adMHQfVKdlfBCTPb5O4Cm/sVW8HUJHt3GqfQ6Lga2SQaPqOGu2+4aB0YblUXFIRGf3JVccCpKQV8jyCgGUGmhsjMJh22xA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589493169; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=gShyhjqjbHJy6eFf39LF/373DISXPXwLsLglaCjPWGo=; b=J75lwnTtkt7LKzJfO6hFh7W2ROljMO2zae7sxYoOZyjH1yqvemO1FZuxtPZbkEpedrJ1r1ziOkJEu1Wmtkx1P7iggn/expHmckWRcHArKR8wxcP7ooSMULwFBpIOaWEhtlEAZw+mZcmRHlqJWnaiVwTgmyLQs9CWUC+9DLb6LxM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+59603+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1589493169320788.1672309835404; Thu, 14 May 2020 14:52:49 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 2BKWYY1788612xjK7OxPl7gV; Thu, 14 May 2020 14:52:48 -0700 X-Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mx.groups.io with SMTP id smtpd.web11.1970.1589493168169412090 for ; Thu, 14 May 2020 14:52:48 -0700 IronPort-SDR: Mp9sSl03ZmPC1zTAJhL4e5WRKMHNhK8pmUeUiiyUQEcrhGCSlsCiyawJk97ODfSJjKSd819/mu 21hGBlBCTtQA== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 May 2020 14:52:47 -0700 IronPort-SDR: 0tvgk3gigW68QuZSnT8Wdsu6VmHraI6vAWYonQ+IsS6HrMM9I9te/S05SlpfGPDzV31ps1nF0T Q+/32XX6GufA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,392,1583222400"; d="scan'208";a="410233830" X-Received: from shwdeopenpsi174.ccr.corp.intel.com ([10.239.157.39]) by orsmga004.jf.intel.com with ESMTP; 14 May 2020 14:52:44 -0700 From: "Xu, Wei6" To: devel@edk2.groups.io Cc: Michael D Kinney , Liming Gao , Sean Brogan Subject: [edk2-devel] [PATCH V3 1/5] FmpDevicePkg: Add FmpDependency library class and BASE instance Date: Fri, 15 May 2020 05:52:28 +0800 Message-Id: <20200514215232.13372-2-wei6.xu@intel.com> In-Reply-To: <20200514215232.13372-1-wei6.xu@intel.com> References: <20200514215232.13372-1-wei6.xu@intel.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,wei6.xu@intel.com X-Gm-Message-State: xFUN8QGbNOAtdRwcavzGLrPLx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1589493168; bh=gZuPHXZakjE7m2B3d3OOIXrULjer6OFVKeJT/f9InZw=; h=Cc:Date:From:Reply-To:Subject:To; b=gfI20SPa5l2C8QwG14hbWYcLIP7At9t8Z3AqESa+akB2bQoY2s/Z+hy1cejEEYsHeE9 w8bihYr4Jvf1fldP/EZxFoi2b+qUPjyFfmV8XzuwfvQQQV7VbNFQAcVtk8pcaS8kIFp1q bJJwuGxk13HWq/Yz6ZK7LT7UkYTnw2d5G+c= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2696 This library provides services to evaluate Fmp capsule dependency expression, validate dependency expression and get dependency from firmware image. Cc: Michael D Kinney Cc: Liming Gao Cc: Sean Brogan Signed-off-by: Wei6 Xu Reviewed-by: Sean Brogan --- FmpDevicePkg/FmpDevicePkg.dec | 6 +- FmpDevicePkg/FmpDevicePkg.dsc | 4 +- FmpDevicePkg/Include/Library/FmpDependencyLib.h | 89 ++++ .../Library/FmpDependencyLib/FmpDependencyLib.c | 546 +++++++++++++++++= ++++ .../Library/FmpDependencyLib/FmpDependencyLib.inf | 34 ++ .../Library/FmpDependencyLib/FmpDependencyLib.uni | 12 + 6 files changed, 689 insertions(+), 2 deletions(-) create mode 100644 FmpDevicePkg/Include/Library/FmpDependencyLib.h create mode 100644 FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c create mode 100644 FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.= inf create mode 100644 FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.= uni diff --git a/FmpDevicePkg/FmpDevicePkg.dec b/FmpDevicePkg/FmpDevicePkg.dec index 55671878dd..4947008346 100644 --- a/FmpDevicePkg/FmpDevicePkg.dec +++ b/FmpDevicePkg/FmpDevicePkg.dec @@ -5,11 +5,11 @@ # instance that supports the update of firmware storage devices using UEFI # Capsules. The behavior of the Firmware Management Protocol instance is # customized using libraries and PCDs. # # Copyright (c) 2016, Microsoft Corporation. All rights reserved.
-# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # ## =20 @@ -33,10 +33,14 @@ =20 ## @libraryclass Provides firmware device specific services to support # updates of a firmware image stored in a firmware devi= ce. FmpDeviceLib|Include/Library/FmpDeviceLib.h =20 + ## @libraryclass Provides generic services to support capsule dependen= cy + # expression evaluation. + FmpDependencyLib|Include/Library/FmpDependencyLib.h + [LibraryClasses.Common.Private] ## @libraryclass Provides services to retrieve values from a capsule's= FMP # Payload Header. The structure is not included in the # library class. Instead, services are provided to ret= rieve # information from the FMP Payload Header. If informat= ion is diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc index b8fb9d7c19..dfb3c1a141 100644 --- a/FmpDevicePkg/FmpDevicePkg.dsc +++ b/FmpDevicePkg/FmpDevicePkg.dsc @@ -5,11 +5,11 @@ # instance that supports the update of firmware storage devices using UEFI # Capsules. The behavior of the Firmware Management Protocol instance is # customized using libraries and PCDs. # # Copyright (c) 2016, Microsoft Corporation. All rights reserved.
-# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All right= s reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -58,10 +58,11 @@ !endif FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAu= thenticationLibPkcs7.inf CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/C= apsuleUpdatePolicyLibNull.inf FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloa= dHeaderLibV1.inf FmpDeviceLib|FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf + FmpDependencyLib|FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.= inf TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplat= e.inf =20 [LibraryClasses.ARM, LibraryClasses.AARCH64] # # It is not possible to prevent the ARM compiler for generic intrinsic f= unctions. @@ -86,10 +87,11 @@ # FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNu= ll.inf FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolic= yLibOnProtocol.inf FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf + FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf FmpDevicePkg/FmpDxe/FmpDxeLib.inf =20 # # Modules # diff --git a/FmpDevicePkg/Include/Library/FmpDependencyLib.h b/FmpDevicePkg= /Include/Library/FmpDependencyLib.h new file mode 100644 index 0000000000..1a191ca6ee --- /dev/null +++ b/FmpDevicePkg/Include/Library/FmpDependencyLib.h @@ -0,0 +1,89 @@ +/** @file + Fmp Capsule Dependency support functions for Firmware Management Protoco= l based + firmware updates. + + Copyright (c) 2020, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __FMP_DEPENDENCY_LIB__ +#define __FMP_DEPENDENCY_LIB__ + +#include +#include + +// +// Data struct to store FMP ImageType and version for dependency check. +// +typedef struct { + EFI_GUID ImageTypeId; + UINT32 Version; +} FMP_DEPEX_CHECK_VERSION_DATA; + +/** + 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. + + @retval TRUE The capsule is valid. + @retval FALSE The capsule is invalid. + +**/ +BOOLEAN +EFIAPI +ValidateDependency ( + IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, + IN CONST UINTN MaxDepexSize, + OUT UINT32 *DepexSize + ); + +/** + 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. + + @retval The pointer to dependency. + @retval Null + +**/ +EFI_FIRMWARE_IMAGE_DEP* +EFIAPI +GetImageDependency ( + IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image, + IN UINTN ImageSize, + OUT UINT32 *DepexSize + ); + +/** + Evaluate the dependencies. The caller must search all the Fmp instances = and + gather their versions into FmpVersions parameter. If there is PUSH_GUID = opcode + in dependency expression with no FmpVersions provided, the dependency wi= ll + evaluate to FALSE. + + @param[in] Dependencies Dependency expressions. + @param[in] DependenciesSize Size of Dependency expressions. + @param[in] FmpVersions Array of Fmp ImageTypeId and version. Th= is + parameter is optional and can be set to = NULL. + @param[in] FmpVersionsCount Element count of the array. When FmpVers= ions + is NULL, FmpVersionsCount must be 0. + + @retval TRUE Dependency expressions evaluate to TRUE. + @retval FALSE Dependency expressions evaluate to FALSE. + +**/ +BOOLEAN +EFIAPI +EvaluateDependency ( + IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, + IN UINTN DependenciesSize, + IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions OPTIONAL, + IN UINTN FmpVersionsCount + ); + +#endif diff --git a/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c b/Fmp= DevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c new file mode 100644 index 0000000000..a8083bff12 --- /dev/null +++ b/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c @@ -0,0 +1,546 @@ +/** @file + Supports Fmp Capsule Dependency Expression. + + Copyright (c) 2020, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include +#include +#include + +// +// Define the initial size of the dependency expression evaluation stack +// +#define DEPEX_STACK_SIZE_INCREMENT 0x1000 + +// +// Type of stack element +// +typedef enum { + BooleanType, + VersionType +} ELEMENT_TYPE; + +// +// Value of stack element +// +typedef union { + BOOLEAN Boolean; + UINT32 Version; +} ELEMENT_VALUE; + +// +// Stack element used to evaluate dependency expressions +// +typedef struct { + ELEMENT_VALUE Value; + ELEMENT_TYPE Type; +} DEPEX_ELEMENT; + +// +// Global stack used to evaluate dependency expressions +// +DEPEX_ELEMENT *mDepexEvaluationStack =3D NULL; +DEPEX_ELEMENT *mDepexEvaluationStackEnd =3D NULL; +DEPEX_ELEMENT *mDepexEvaluationStackPointer =3D NULL; + +/** + Grow size of the Depex stack + + @retval EFI_SUCCESS Stack successfully growed. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow = the stack. + +**/ +EFI_STATUS +GrowDepexStack ( + VOID + ) +{ + DEPEX_ELEMENT *NewStack; + UINTN Size; + + Size =3D DEPEX_STACK_SIZE_INCREMENT; + if (mDepexEvaluationStack !=3D NULL) { + Size =3D Size + (mDepexEvaluationStackEnd - mDepexEvaluationStack); + } + + NewStack =3D AllocatePool (Size * sizeof (DEPEX_ELEMENT)); + if (NewStack =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "GrowDepexStack: Cannot allocate memory for depen= dency evaluation stack!\n")); + return EFI_OUT_OF_RESOURCES; + } + + if (mDepexEvaluationStack !=3D NULL) { + // + // Copy to Old Stack to the New Stack + // + CopyMem ( + NewStack, + mDepexEvaluationStack, + (mDepexEvaluationStackEnd - mDepexEvaluationStack) * sizeof (DEPEX_E= LEMENT) + ); + + // + // Free The Old Stack + // + FreePool (mDepexEvaluationStack); + } + + // + // Make the Stack pointer point to the old data in the new stack + // + mDepexEvaluationStackPointer =3D NewStack + (mDepexEvaluationStackPointe= r - mDepexEvaluationStack); + mDepexEvaluationStack =3D NewStack; + mDepexEvaluationStackEnd =3D NewStack + Size; + + return EFI_SUCCESS; +} + +/** + Push an element onto the Stack. + + @param[in] Value Value to push. + @param[in] Type Element Type + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + @retval EFI_INVALID_PARAMETER Wrong stack element type. + +**/ +EFI_STATUS +Push ( + IN UINT32 Value, + IN UINTN Type + ) +{ + EFI_STATUS Status; + DEPEX_ELEMENT Element; + + // + // Check Type + // + if (Type !=3D BooleanType && Type !=3D VersionType) { + return EFI_INVALID_PARAMETER; + } + + // + // Check for a stack overflow condition + // + if (mDepexEvaluationStackPointer =3D=3D mDepexEvaluationStackEnd) { + // + // Grow the stack + // + Status =3D GrowDepexStack (); + if (EFI_ERROR (Status)) { + return Status; + } + } + + Element.Value.Version =3D Value; + Element.Type =3D Type; + + // + // Push the item onto the stack + // + *mDepexEvaluationStackPointer =3D Element; + mDepexEvaluationStackPointer++; + + return EFI_SUCCESS; +} + +/** + Pop an element from the stack. + + @param[out] Element Element to pop. + @param[in] Type Type of element. + + @retval EFI_SUCCESS The value was popped onto the stack. + @retval EFI_ACCESS_DENIED The pop operation underflowed the stack. + @retval EFI_INVALID_PARAMETER Type is mismatched. + +**/ +EFI_STATUS +Pop ( + OUT DEPEX_ELEMENT *Element, + IN ELEMENT_TYPE Type + ) +{ + // + // Check for a stack underflow condition + // + if (mDepexEvaluationStackPointer =3D=3D mDepexEvaluationStack) { + DEBUG ((DEBUG_ERROR, "EvaluateDependency: Stack underflow!\n")); + return EFI_ACCESS_DENIED; + } + + // + // Pop the item off the stack + // + mDepexEvaluationStackPointer--; + *Element =3D *mDepexEvaluationStackPointer; + if ((*Element).Type !=3D Type) { + DEBUG ((DEBUG_ERROR, "EvaluateDependency: Popped element type is misma= tched!\n")); + return EFI_INVALID_PARAMETER; + } + return EFI_SUCCESS; +} + +/** + Evaluate the dependencies. The caller must search all the Fmp instances = and + gather their versions into FmpVersions parameter. If there is PUSH_GUID = opcode + in dependency expression with no FmpVersions provided, the dependency wi= ll + evaluate to FALSE. + + @param[in] Dependencies Dependency expressions. + @param[in] DependenciesSize Size of Dependency expressions. + @param[in] FmpVersions Array of Fmp ImageTypeId and version. Th= is + parameter is optional and can be set to = NULL. + @param[in] FmpVersionsCount Element count of the array. When FmpVers= ions + is NULL, FmpVersionsCount must be 0. + + @retval TRUE Dependency expressions evaluate to TRUE. + @retval FALSE Dependency expressions evaluate to FALSE. + +**/ +BOOLEAN +EFIAPI +EvaluateDependency ( + IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, + IN UINTN DependenciesSize, + IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions OPTIONAL, + IN UINTN FmpVersionsCount + ) +{ + EFI_STATUS Status; + UINT8 *Iterator; + UINT8 Index; + DEPEX_ELEMENT Element1; + DEPEX_ELEMENT Element2; + GUID ImageTypeId; + UINT32 Version; + + // + // Check if parameter is valid. + // + if (Dependencies =3D=3D NULL || DependenciesSize =3D=3D 0) { + return FALSE; + } + + if (FmpVersions =3D=3D NULL && FmpVersionsCount > 0) { + return FALSE; + } + + // + // Clean out memory leaks in Depex Boolean stack. Leaks are only caused = by + // incorrectly formed DEPEX expressions + // + mDepexEvaluationStackPointer =3D mDepexEvaluationStack; + + Iterator =3D (UINT8 *) Dependencies->Dependencies; + while (Iterator < (UINT8 *) Dependencies->Dependencies + DependenciesSiz= e) { + switch (*Iterator) + { + case EFI_FMP_DEP_PUSH_GUID: + if (Iterator + sizeof (EFI_GUID) >=3D (UINT8 *) Dependencies->Depend= encies + DependenciesSize) { + DEBUG ((DEBUG_ERROR, "EvaluateDependency: GUID extends beyond end = of dependency expression!\n")); + goto Error; + } + + CopyGuid (&ImageTypeId, (EFI_GUID *) (Iterator + 1)); + Iterator =3D Iterator + sizeof (EFI_GUID); + + for (Index =3D 0; Index < FmpVersionsCount; Index ++) { + if(CompareGuid (&FmpVersions[Index].ImageTypeId, &ImageTypeId)){ + Status =3D Push (FmpVersions[Index].Version, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + } + } + if (Index =3D=3D FmpVersionsCount) { + DEBUG ((DEBUG_ERROR, "EvaluateDependency: %g is not found!\n", &Im= ageTypeId)); + goto Error; + } + break; + case EFI_FMP_DEP_PUSH_VERSION: + if (Iterator + sizeof (UINT32) >=3D (UINT8 *) Dependencies->Dependen= cies + DependenciesSize ) { + DEBUG ((DEBUG_ERROR, "EvaluateDependency: VERSION extends beyond e= nd of dependency expression!\n")); + goto Error; + } + + Version =3D *(UINT32 *) (Iterator + 1); + Status =3D Push (Version, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Iterator =3D Iterator + sizeof (UINT32); + break; + case EFI_FMP_DEP_VERSION_STR: + Iterator +=3D AsciiStrnLenS ((CHAR8 *) Iterator, DependenciesSize - = (Iterator - Dependencies->Dependencies)); + if (Iterator =3D=3D (UINT8 *) Dependencies->Dependencies + Dependenc= iesSize) { + DEBUG ((DEBUG_ERROR, "EvaluateDependency: STRING extends beyond en= d of dependency expression!\n")); + } + break; + case EFI_FMP_DEP_AND: + Status =3D Pop (&Element1, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop (&Element2, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Push (Element1.Value.Boolean & Element2.Value.Boolean, Bo= oleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_OR: + Status =3D Pop (&Element1, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop(&Element2, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Push (Element1.Value.Boolean | Element2.Value.Boolean, Bo= oleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_NOT: + Status =3D Pop (&Element1, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Push (!(Element1.Value.Boolean), BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_TRUE: + Status =3D Push (TRUE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_FALSE: + Status =3D Push (FALSE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_EQ: + Status =3D Pop (&Element1, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop (&Element2, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D (Element1.Value.Version =3D=3D Element2.Value.Version) ? = Push (TRUE, BooleanType) : Push (FALSE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_GT: + Status =3D Pop (&Element1, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop (&Element2, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D (Element1.Value.Version > Element2.Value.Version) ? Push= (TRUE, BooleanType) : Push (FALSE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_GTE: + Status =3D Pop (&Element1, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop (&Element2, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D (Element1.Value.Version >=3D Element2.Value.Version) ? Pu= sh (TRUE, BooleanType) : Push (FALSE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_LT: + Status =3D Pop (&Element1, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop (&Element2, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D (Element1.Value.Version < Element2.Value.Version) ? Push= (TRUE, BooleanType) : Push (FALSE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_LTE: + Status =3D Pop (&Element1, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop (&Element2, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D (Element1.Value.Version <=3D Element2.Value.Version) ? Pu= sh (TRUE, BooleanType) : Push (FALSE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_END: + Status =3D Pop (&Element1, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + return Element1.Value.Boolean; + default: + DEBUG ((DEBUG_ERROR, "EvaluateDependency: Unknown Opcode - %02x!\n",= *Iterator)); + goto Error; + } + Iterator++; + } + + DEBUG ((DEBUG_ERROR, "EvaluateDependency: No EFI_FMP_DEP_END Opcode in e= xression!\n")); + +Error: + 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. + + @retval TRUE The capsule is valid. + @retval FALSE The capsule is invalid. + +**/ +BOOLEAN +EFIAPI +ValidateDependency ( + IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, + IN CONST UINTN MaxDepexSize, + OUT UINT32 *DepexSize + ) +{ + UINT8 *Depex; + + if (DepexSize !=3D NULL) { + *DepexSize =3D 0; + } + + if (Dependencies =3D=3D NULL) { + return FALSE; + } + + Depex =3D Dependencies->Dependencies; + while (Depex < Dependencies->Dependencies + MaxDepexSize) { + switch (*Depex) + { + case EFI_FMP_DEP_PUSH_GUID: + Depex +=3D sizeof (EFI_GUID) + 1; + break; + case EFI_FMP_DEP_PUSH_VERSION: + Depex +=3D sizeof (UINT32) + 1; + break; + case EFI_FMP_DEP_VERSION_STR: + Depex +=3D AsciiStrnLenS ((CHAR8 *) Depex, Dependencies->Dependencie= s + MaxDepexSize - Depex) + 1; + break; + case EFI_FMP_DEP_AND: + case EFI_FMP_DEP_OR: + case EFI_FMP_DEP_NOT: + case EFI_FMP_DEP_TRUE: + case EFI_FMP_DEP_FALSE: + case EFI_FMP_DEP_EQ: + case EFI_FMP_DEP_GT: + case EFI_FMP_DEP_GTE: + case EFI_FMP_DEP_LT: + case EFI_FMP_DEP_LTE: + Depex +=3D 1; + break; + case EFI_FMP_DEP_END: + Depex +=3D 1; + if (DepexSize !=3D NULL) { + *DepexSize =3D (UINT32)(Depex - Dependencies->Dependencies); + } + return TRUE; + default: + return FALSE; + } + } + + 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. + + @retval The pointer to dependency. + @retval Null + +**/ +EFI_FIRMWARE_IMAGE_DEP* +EFIAPI +GetImageDependency ( + IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image, + IN UINTN ImageSize, + OUT UINT32 *DepexSize + ) +{ + EFI_FIRMWARE_IMAGE_DEP *Depex; + UINTN MaxDepexSize; + + if (Image =3D=3D NULL) { + return NULL; + } + + // + // Check to make sure that operation can be safely performed. + // + if (((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr= .dwLength) < (UINTN)Image || \ + ((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr= .dwLength) >=3D (UINTN)Image + ImageSize) { + // + // Pointer overflow. Invalid image. + // + return NULL; + } + + Depex =3D (EFI_FIRMWARE_IMAGE_DEP*)((UINT8 *)Image + sizeof (Image->Mono= tonicCount) + Image->AuthInfo.Hdr.dwLength); + MaxDepexSize =3D ImageSize - (sizeof (Image->MonotonicCount) + Image->Au= thInfo.Hdr.dwLength); + + // + // Validate the dependency and get the size of dependency + // + if (ValidateDependency (Depex, MaxDepexSize, DepexSize)) { + return Depex; + } + + return NULL; +} + diff --git a/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf b/F= mpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf new file mode 100644 index 0000000000..b7e5c8d002 --- /dev/null +++ b/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf @@ -0,0 +1,34 @@ +## @file +# Provides Fmp Capsule Dependency Expression support. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D FmpDependencyLib + MODULE_UNI_FILE =3D FmpDependencyLib.uni + FILE_GUID =3D 67F55EA4-B4CF-4A08-931B-0BBCF1E0F7A3 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D FmpDependencyLib + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 ARM AARCH64 +# + +[Sources] + FmpDependencyLib.c + +[Packages] + MdePkg/MdePkg.dec + FmpDevicePkg/FmpDevicePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + BaseMemoryLib diff --git a/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.uni b/F= mpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.uni new file mode 100644 index 0000000000..422a96b570 --- /dev/null +++ b/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.uni @@ -0,0 +1,12 @@ +// /** @file +// Provides Fmp Capsule Dependency Expression support. +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "FMP Dependency Lib" + +#string STR_MODULE_DESCRIPTION #language en-US "Provides Fmp Capsule Dep= endency Expression support." --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#59603): https://edk2.groups.io/g/devel/message/59603 Mute This Topic: https://groups.io/mt/74215661/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Tue Apr 16 13:31:03 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+59604+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+59604+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1589493170; cv=none; d=zohomail.com; s=zohoarc; b=X3SSvZV7hm+5YP7Om87O5xdvmLSo6RgjoUBFsDPwu834GkDgRanq8HVS7tbAs22p5B4I3EMB9FjqT0Lx/rxT+GwpyVrw3SGpi5MzhsrQPri8n9E2/SlWmSCrQ5fYAmvCpQn6OfZUpNEx9dY4KcoGV6BUJ0kDIsY7LuXXjgPFf2w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589493170; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=k9MKQ0zEouekrmRerSLNqW8Ftd1rH7/dfVEI0vAj5CI=; b=AlqzoW0/lOCOnizHPUQga7WMoG5b7sUXDuk45uGtBUEfKLjlYb9pgrMTIFzjY1ni+AZLRHli7OpC3DYNB3iL7a0WWCCYGIO0miFkxDx6bJmYEu8keGf7kJJgnqDsNtgr1JiuxuLkRrGKX89lWO96AxdycLfW9lde4xgPqcyAJsA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+59604+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1589493170896320.9406291757813; Thu, 14 May 2020 14:52:50 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id KwL8YY1788612xd6gtvD4K58; Thu, 14 May 2020 14:52:50 -0700 X-Received: from mga04.intel.com (mga04.intel.com []) by mx.groups.io with SMTP id smtpd.web11.1970.1589493168169412090 for ; Thu, 14 May 2020 14:52:50 -0700 IronPort-SDR: g6DASuXceRouD6CU/WAfgC2pdsVKGEXkFy98E2yKZCn/Pptxc8YiktmZIDHYmYnF/Fe6r6roSj jpUALaj3tS4Q== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 May 2020 14:52:49 -0700 IronPort-SDR: r+wDwuXVGdMduMa+djRmogI1+aI8UCg1Ke6uRgne+ihFVTQE/bHINU2Lz7Y2gsUsPsYue8Wnbo rwbqy1Y03fGg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,392,1583222400"; d="scan'208";a="410233851" X-Received: from shwdeopenpsi174.ccr.corp.intel.com ([10.239.157.39]) by orsmga004.jf.intel.com with ESMTP; 14 May 2020 14:52:47 -0700 From: "Xu, Wei6" To: devel@edk2.groups.io Cc: Michael D Kinney , Liming Gao , Sean Brogan Subject: [edk2-devel] [PATCH V3 2/5] FmpDevicePkg/Test: Add FmpDependencyLib unit test Date: Fri, 15 May 2020 05:52:29 +0800 Message-Id: <20200514215232.13372-3-wei6.xu@intel.com> In-Reply-To: <20200514215232.13372-1-wei6.xu@intel.com> References: <20200514215232.13372-1-wei6.xu@intel.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,wei6.xu@intel.com X-Gm-Message-State: bS7vagnFvNCn7HXoP4WWG0Tfx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1589493170; bh=ndj3pf4+7GyAqAqb92EePnx3158TYO/q2TRtq0AH5og=; h=Cc:Date:From:Reply-To:Subject:To; b=bIhNE8fOBtJ+soaI/aq/e9LTRDpXJyVFQHZvSldSxSIIBrsDE3Q98YTlaTykzlt7JZv 9BOxvd4ifbgVAK1EMZ4NPPCIEK+88aXx4TRrUnU+H8+lDN/dlZxaOHk9iIOv7lf/qD8j9 7GheyeqSFSgAg3FZUik2owewdj4WM1QFNgs= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2696 * Add unit tests for EvaluateDependency API in FmpDependencyLib. * Add Test/FmpDeviceHostPkgTest.dsc to build host based unit test. * Update FmpDevicePkg.dsc to build target based unit test. * Update FmpDevicePkg.ci.yaml to build and run host based test. Cc: Michael D Kinney Cc: Liming Gao Cc: Sean Brogan Signed-off-by: Wei6 Xu --- FmpDevicePkg/FmpDevicePkg.ci.yaml | 10 + FmpDevicePkg/FmpDevicePkg.dsc | 7 + FmpDevicePkg/Test/FmpDeviceHostPkgTest.dsc | 28 +++ .../FmpDependencyLib/EvaluateDependencyUnitTest.c | 270 +++++++++++++++++= ++++ .../FmpDependencyLibUnitTestsHost.inf | 34 +++ .../FmpDependencyLibUnitTestsUefi.inf | 35 +++ 6 files changed, 384 insertions(+) create mode 100644 FmpDevicePkg/Test/FmpDeviceHostPkgTest.dsc create mode 100644 FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/Eva= luateDependencyUnitTest.c create mode 100644 FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/Fmp= DependencyLibUnitTestsHost.inf create mode 100644 FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/Fmp= DependencyLibUnitTestsUefi.inf diff --git a/FmpDevicePkg/FmpDevicePkg.ci.yaml b/FmpDevicePkg/FmpDevicePkg.= ci.yaml index c17b355d42..74a0aefe8e 100644 --- a/FmpDevicePkg/FmpDevicePkg.ci.yaml +++ b/FmpDevicePkg/FmpDevicePkg.ci.yaml @@ -6,26 +6,36 @@ ## { "CompilerPlugin": { "DscPath": "FmpDevicePkg.dsc" }, + "HostUnitTestCompilerPlugin": { + "DscPath": "Test/FmpDeviceHostPkgTest.dsc" + }, "CharEncodingCheck": { "IgnoreFiles": [] }, "DependencyCheck": { "AcceptableDependencies": [ "MdePkg/MdePkg.dec", "MdeModulePkg/MdeModulePkg.dec", "FmpDevicePkg/FmpDevicePkg.dec", "CryptoPkg/CryptoPkg.dec" ], + "AcceptableDependencies-HOST_APPLICATION":[ + "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec" + ], "IgnoreInf": [] }, "DscCompleteCheck": { "DscPath": "FmpDevicePkg.dsc", "IgnoreInf": [] }, + "HostUnitTestDscCompleteCheck": { + "IgnoreInf": [], + "DscPath": "Test/FmpDeviceHostPkgTest.dsc" + }, "GuidCheck": { "IgnoreGuidName": [], "IgnoreGuidValue": [], "IgnoreFoldersAndFiles": [] }, diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc index dfb3c1a141..49c6ff3a30 100644 --- a/FmpDevicePkg/FmpDevicePkg.dsc +++ b/FmpDevicePkg/FmpDevicePkg.dsc @@ -34,10 +34,12 @@ # TRUE - Build FmpDxe module for with storage access enabled # FALSE - Build FmpDxe module for with storage access disabled # DEFINE DEVICE_FMP_STORAGE_ACCESS_ENABLE =3D TRUE =20 +!include UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc + [LibraryClasses] UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry= Point.inf UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBoo= tServicesTableLib.inf UefiLib|MdePkg/Library/UefiLib/UefiLib.inf UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/U= efiRuntimeServicesTableLib.inf @@ -161,7 +163,12 @@ # in a system firmware image. # CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNu= ll/CapsuleUpdatePolicyLibNull.inf } =20 + # + # Add UEFI Target Based Unit Tests + # + FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnit= TestsUefi.inf + [BuildOptions] *_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/FmpDevicePkg/Test/FmpDeviceHostPkgTest.dsc b/FmpDevicePkg/Test= /FmpDeviceHostPkgTest.dsc new file mode 100644 index 0000000000..83574399be --- /dev/null +++ b/FmpDevicePkg/Test/FmpDeviceHostPkgTest.dsc @@ -0,0 +1,28 @@ +## @file +# FmpDevicePkg DSC file used to build host-based unit tests. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + PLATFORM_NAME =3D FmpDevicePkgHostTest + PLATFORM_GUID =3D 80B12646-9A30-4516-AABF-DE1919B573E3 + PLATFORM_VERSION =3D 0.1 + DSC_SPECIFICATION =3D 0x00010005 + OUTPUT_DIRECTORY =3D Build/FmpDevicePkg/HostTest + SUPPORTED_ARCHITECTURES =3D IA32|X64 + BUILD_TARGETS =3D NOOPT + SKUID_IDENTIFIER =3D DEFAULT + +!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc + +[LibraryClasses] + FmpDependencyLib|FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.= inf + +[Components] + # + # Build HOST_APPLICATION that tests the FmpDependencyLib + # + FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnit= TestsHost.inf diff --git a/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/EvaluateDe= pendencyUnitTest.c b/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/Ev= aluateDependencyUnitTest.c new file mode 100644 index 0000000000..f8ccdd906f --- /dev/null +++ b/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/EvaluateDependenc= yUnitTest.c @@ -0,0 +1,270 @@ +/** @file + Unit tests of EvaluateDependency API in FmpDependencyLib. + + Copyright (c) 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +#define UNIT_TEST_APP_NAME "FmpDependencyLib Unit Test Application" +#define UNIT_TEST_APP_VERSION "1.0" + +typedef struct { + UINT8 *Dependencies; + UINTN DependenciesSize; + BOOLEAN ExpectedResult; +} BASIC_TEST_CONTEXT; + +// +// Image Type ID of FMP device A +// +#define IMAGE_TYPE_ID_1 { 0x97144DFA, 0xEB8E, 0xD14D, {0x8B, 0x4D, 0x39,= 0x88, 0x24, 0x96, 0x56, 0x42}} + +// +// Image Type ID of FMP device B +// +#define IMAGE_TYPE_ID_2 { 0xA42A7370, 0x433A, 0x684D, {0x9A, 0xA1, 0xDE,= 0x62, 0x23, 0x30, 0x6C, 0xF3}} + +// +// Device A's version is 0x00000002 +// Device B's version is 0x00000003 +// +static FMP_DEPEX_CHECK_VERSION_DATA mFmpVersions[] =3D { + {IMAGE_TYPE_ID_1, 0x00000002}, + {IMAGE_TYPE_ID_2, 0x00000003} +}; + +// Valid Dependency Expression 1: (Version(A) > 0x00000001) && (Version(B)= >=3D 0x00000003) +static UINT8 mExpression1[] =3D { + EFI_FMP_DEP_PUSH_VERSION, 0x01, 0x00, 0x00, 0x00, + EFI_FMP_DEP_PUSH_GUID, 0xFA, 0x4D, 0x14, 0x97, 0x8E, 0xEB, 0x4D, 0xD1, 0= x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42, + EFI_FMP_DEP_GT, + EFI_FMP_DEP_PUSH_VERSION, 0x03, 0x00, 0x00, 0x00, + EFI_FMP_DEP_PUSH_GUID, 0x70, 0x73, 0x2A, 0xA4, 0x3A, 0x43, 0x4D, 0x68, 0= x9A, 0xA1, 0xDE, 0x62, 0x23, 0x30, 0x6C, 0xF3, + EFI_FMP_DEP_GTE, + EFI_FMP_DEP_AND, + EFI_FMP_DEP_END +}; + +// Valid Dependency Expression 2: (Version(A) < 0x00000002) || (Version(B)= <=3D 0x00000003) +static UINT8 mExpression2[] =3D { + EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00, + EFI_FMP_DEP_PUSH_GUID, 0xFA, 0x4D, 0x14, 0x97, 0x8E, 0xEB, 0x4D, 0xD1, 0= x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42, + EFI_FMP_DEP_LT, + EFI_FMP_DEP_PUSH_VERSION, 0x03, 0x00, 0x00, 0x00, + EFI_FMP_DEP_PUSH_GUID, 0x70, 0x73, 0x2A, 0xA4, 0x3A, 0x43, 0x4D, 0x68, 0= x9A, 0xA1, 0xDE, 0x62, 0x23, 0x30, 0x6C, 0xF3, + EFI_FMP_DEP_LTE, + EFI_FMP_DEP_OR, + EFI_FMP_DEP_END +}; + +// Valid Dependency Expression 3: !(Version(A) =3D=3D 0x0000002) +static UINT8 mExpression3[] =3D { + EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00, + EFI_FMP_DEP_PUSH_GUID, 0xFA, 0x4D, 0x14, 0x97, 0x8E, 0xEB, 0x4D, 0xD1, 0= x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42, + EFI_FMP_DEP_EQ, + EFI_FMP_DEP_NOT, + EFI_FMP_DEP_END +}; + +// Valid Dependency Expression 4: "Test" TRUE && FALSE +static UINT8 mExpression4[] =3D { + EFI_FMP_DEP_VERSION_STR, 'T', 'e', 's', 't', '\0', + EFI_FMP_DEP_TRUE, + EFI_FMP_DEP_FALSE, + EFI_FMP_DEP_AND, + EFI_FMP_DEP_END +}; + +// Invalid Dependency Expression 1: Invalid Op-code +static UINT8 mExpression5[] =3D {EFI_FMP_DEP_TRUE, 0xAA, EFI_FMP_DEP_END}; + +// Invalid Dependency Expression 2: String doesn't end with '\0' +static UINT8 mExpression6[] =3D {EFI_FMP_DEP_VERSION_STR, 'T', 'e', 's', '= t', EFI_FMP_DEP_TRUE, EFI_FMP_DEP_END}; + +// Invalid Dependency Expression 3: GUID is in invalid size +static UINT8 mExpression7[] =3D { + EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00, + EFI_FMP_DEP_PUSH_GUID, 0xAA, 0xBB, 0xCC, 0xDD, + EFI_FMP_DEP_GTE, + EFI_FMP_DEP_END +}; + +// Invalid Dependency Expression 4: Version is in invalid size +static UINT8 mExpression8[] =3D { + EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, + EFI_FMP_DEP_PUSH_GUID, 0xDA, 0xCB, 0x25, 0xAC, 0x9E, 0xCD, 0x5E, 0xE2, 0= x9C, 0x5E, 0x4A, 0x99, 0x35, 0xA7, 0x67, 0x53, + EFI_FMP_DEP_GTE, + EFI_FMP_DEP_END +}; + +// Invalid Dependency Expression 5: Operand and operator mismatch +static UINT8 mExpression9[] =3D {EFI_FMP_DEP_TRUE, EFI_FMP_DEP_FALSE, EFI_= FMP_DEP_GTE, EFI_FMP_DEP_END}; + +// Invalid Dependency Expression 6: GUID is NOT FOUND +static UINT8 mExpression10[] =3D { + EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00, + EFI_FMP_DEP_PUSH_GUID, 0xDA, 0xCB, 0x25, 0xAC, 0x9E, 0xCD, 0x5E, 0xE2, 0= x9C, 0x5E, 0x4A, 0x99, 0x35, 0xA7, 0x67, 0x53, + EFI_FMP_DEP_GT, + EFI_FMP_DEP_END +}; + +// Invalid Dependency Expression 7: Stack underflow +static UINT8 mExpression11[] =3D { + EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00, + EFI_FMP_DEP_GT, + EFI_FMP_DEP_END +}; + +// ------------------------------------------------Test Depex------Depex S= ize----------------Expected Result +static BASIC_TEST_CONTEXT mBasicTestTrue1 =3D {mExpression1, sizeo= f(mExpression1), TRUE}; +static BASIC_TEST_CONTEXT mBasicTestTrue2 =3D {mExpression2, sizeo= f(mExpression2), TRUE}; +static BASIC_TEST_CONTEXT mBasicTestFalse1 =3D {mExpression3, sizeo= f(mExpression3), FALSE}; +static BASIC_TEST_CONTEXT mBasicTestFalse2 =3D {mExpression4, sizeo= f(mExpression4), FALSE}; +static BASIC_TEST_CONTEXT mBasicTestInvalid1 =3D {mExpression1, sizeo= f(mExpression1) - 1, FALSE}; +static BASIC_TEST_CONTEXT mBasicTestInvalid2 =3D {mExpression5, sizeo= f(mExpression5), FALSE}; +static BASIC_TEST_CONTEXT mBasicTestInvalid3 =3D {mExpression6, sizeo= f(mExpression6), FALSE}; +static BASIC_TEST_CONTEXT mBasicTestInvalid4 =3D {mExpression7, sizeo= f(mExpression7), FALSE}; +static BASIC_TEST_CONTEXT mBasicTestInvalid5 =3D {mExpression8, sizeo= f(mExpression8), FALSE}; +static BASIC_TEST_CONTEXT mBasicTestInvalid6 =3D {mExpression9, sizeo= f(mExpression9), FALSE}; +static BASIC_TEST_CONTEXT mBasicTestInvalid7 =3D {mExpression10, sizeo= f(mExpression10), FALSE}; +static BASIC_TEST_CONTEXT mBasicTestInvalid8 =3D {mExpression11, sizeo= f(mExpression11), FALSE}; + +/** + Unit test for EvaluateDependency() API of the FmpDependencyLib. + + @param[in] Context [Optional] An optional parameter that enables: + 1) test-case reuse with varied parameters and + 2) test-case re-entry for Target tests that need a + reboot. This parameter is a VOID* and it is the + responsibility of the test author to ensure that = the + contents are well understood by all test cases th= at may + consume it. + + @retval UNIT_TEST_PASSED The Unit test has completed and th= e test + case was successful. + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. +**/ +STATIC +UNIT_TEST_STATUS +EFIAPI +EvaluateDependencyTest ( + IN UNIT_TEST_CONTEXT Context + ) +{ + BASIC_TEST_CONTEXT *TestContext; + BOOLEAN EvaluationResult; + + TestContext =3D (BASIC_TEST_CONTEXT *)Context; + + EvaluationResult =3D EvaluateDependency ( + (EFI_FIRMWARE_IMAGE_DEP *)TestContext->Dependencies, + TestContext->DependenciesSize, + mFmpVersions, + sizeof(mFmpVersions)/sizeof(FMP_DEPEX_CHECK_VERSION= _DATA) + ); + + UT_ASSERT_EQUAL (EvaluationResult, TestContext->ExpectedResult); + + return UNIT_TEST_PASSED; +} + +/** + Initialize the unit test framework, suite, and unit tests for the + EvaluateDependency API in FmpDependencyLib and run the unit tests. + + @retval EFI_SUCCESS All test cases were dispatched. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available = to + initialize the unit tests. +**/ +STATIC +EFI_STATUS +EFIAPI +UnitTestingEntry ( + VOID + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Fw; + UNIT_TEST_SUITE_HANDLE DepexEvalTests; + + Fw =3D NULL; + + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSIO= N)); + + // + // Start setting up the test framework for running the tests. + // + Status =3D InitUnitTestFramework (&Fw, UNIT_TEST_APP_NAME, gEfiCallerBas= eName, UNIT_TEST_APP_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status =3D %r= \n", Status)); + goto EXIT; + } + + // + // Populate the Unit Test Suite. + // + Status =3D CreateUnitTestSuite (&DepexEvalTests, Fw, "Evaluate Dependenc= y Test", "FmpDependencyLib.EvaluateDependency", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for DepexEvalTests= \n")); + goto EXIT; + } + + AddTestCase (DepexEvalTests, "Evaluate to True - 1", "Test1", EvaluateDe= pendencyTest, NULL, NULL, &mBasicTestTrue1); + AddTestCase (DepexEvalTests, "Evaluate to True - 2", "Test2", EvaluateDe= pendencyTest, NULL, NULL, &mBasicTestTrue2); + AddTestCase (DepexEvalTests, "Evaluate to False - 1", "Test3", EvaluateD= ependencyTest, NULL, NULL, &mBasicTestFalse1); + AddTestCase (DepexEvalTests, "Evaluate to False - 2", "Test4", EvaluateD= ependencyTest, NULL, NULL, &mBasicTestFalse2); + AddTestCase (DepexEvalTests, "Error: Non-END-terminated expression", "Te= st5", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid1); + AddTestCase (DepexEvalTests, "Error: UNKNOWN Op-Code", "Test6", Evaluate= DependencyTest, NULL, NULL, &mBasicTestInvalid2); + AddTestCase (DepexEvalTests, "Error: Non-Null-terminated string", "Test7= ", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid3); + AddTestCase (DepexEvalTests, "Error: GUID size is not 16", "Test8", Eval= uateDependencyTest, NULL, NULL, &mBasicTestInvalid4); + AddTestCase (DepexEvalTests, "Error: Version size is not 4", "Test9", Ev= aluateDependencyTest, NULL, NULL, &mBasicTestInvalid5); + AddTestCase (DepexEvalTests, "Error: Operand and operator mismatch", "Te= st10", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid6); + AddTestCase (DepexEvalTests, "Error: GUID is NOT FOUND", "Test11", Evalu= ateDependencyTest, NULL, NULL, &mBasicTestInvalid7); + AddTestCase (DepexEvalTests, "Error: Stack Underflow", "Test12", Evaluat= eDependencyTest, NULL, NULL, &mBasicTestInvalid8); + + // + // Execute the tests. + // + Status =3D RunAllTestSuites (Fw); + +EXIT: + if (Fw) { + FreeUnitTestFramework (Fw); + } + + return Status; +} + +/** + Standard UEFI entry point for target based unit test execution from UEFI= Shell. +**/ +EFI_STATUS +EFIAPI +FmpDependencyLibUnitTestAppEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return UnitTestingEntry (); +} + +/** + Standard POSIX C entry point for host based unit test execution. +**/ +int +main ( + int argc, + char *argv[] + ) +{ + return UnitTestingEntry (); +} diff --git a/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDepende= ncyLibUnitTestsHost.inf b/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyL= ib/FmpDependencyLibUnitTestsHost.inf new file mode 100644 index 0000000000..93ae635da5 --- /dev/null +++ b/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibU= nitTestsHost.inf @@ -0,0 +1,34 @@ +## @file +# Unit tests of EvaluateDependency API in FmpDependencyLib that are run fr= om host +# environment. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010006 + BASE_NAME =3D FmpDependencyLibUnitTestsHost + FILE_GUID =3D CE32C647-CAD7-4099-9463-653B932C1691 + MODULE_TYPE =3D HOST_APPLICATION + VERSION_STRING =3D 1.0 + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 +# + +[Sources] + EvaluateDependencyUnitTest.c + +[Packages] + MdePkg/MdePkg.dec + FmpDevicePkg/FmpDevicePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + UnitTestLib + FmpDependencyLib diff --git a/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDepende= ncyLibUnitTestsUefi.inf b/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyL= ib/FmpDependencyLibUnitTestsUefi.inf new file mode 100644 index 0000000000..a2ca369171 --- /dev/null +++ b/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibU= nitTestsUefi.inf @@ -0,0 +1,35 @@ +## @file +# Unit tests of EvaluateDependency API in FmpDependencyLib that are run fr= om UEFI Shell. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010006 + BASE_NAME =3D FmpDependencyLibUnitTestsUefi + FILE_GUID =3D 8FF4C129-C2EF-445D-8658-9A342A1FCC4D + MODULE_TYPE =3D UEFI_APPLICATION + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D FmpDependencyLibUnitTestAppEntry + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 +# + +[Sources] + EvaluateDependencyUnitTest.c + +[Packages] + MdePkg/MdePkg.dec + FmpDevicePkg/FmpDevicePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + UefiApplicationEntryPoint + DebugLib + UnitTestLib + FmpDependencyLib --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#59604): https://edk2.groups.io/g/devel/message/59604 Mute This Topic: https://groups.io/mt/74215662/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Tue Apr 16 13:31:03 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+59605+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+59605+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1589493173; cv=none; d=zohomail.com; s=zohoarc; b=GrntOesVeNbnnmDxgU2t3VGcNySi5gBej2IJtFtHsG9Rq5cGPVUn+yB2RmGS5v6kXobmtq+eqpgi4165Tak9sUIRf1M1/NzHmk+Af35dBvC8/7HseMZ3QnTY9vFrUp10f/RwQksnqdpZKdPDgYrL20nVWh0hnZ6SoLp/O4wsXJw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589493173; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=WS72VRd9JOIRixtOHpS4jG6oyXPCbVwOicAV4ZOgJjE=; b=A9zp53reMhUg2qbYBKofTm4ntrxRc+wGdx8ejqlgGurSEDy9G4aff+lj+M8hKJKH4fUElAYQS/5GHSo+xU2zTAMKeQp7u7g5mYLhkvFQ5ghZGY35iz3DVQZgOz323x3A8feniC2Rfxgs4IXTqwhKWDVwQ+QYmMrdwinxegNMuvI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+59605+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1589493173614331.40097859906143; Thu, 14 May 2020 14:52:53 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id FOMaYY1788612xR0PBK52XKH; Thu, 14 May 2020 14:52:53 -0700 X-Received: from mga04.intel.com (mga04.intel.com []) by mx.groups.io with SMTP id smtpd.web11.1970.1589493168169412090 for ; Thu, 14 May 2020 14:52:52 -0700 IronPort-SDR: KDdXWYiJ7CD4/ipqlVneuZHZEj6sXXJlr5H88hkzwnGyC2V0dwxLxSy29tsUhAxIOntbzlM1H5 Ofdgi/+PBF+A== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 May 2020 14:52:52 -0700 IronPort-SDR: rincHeq/twt0f2/tSi3vU60+CLR0ESg3Urc3FlLtijAriYPFFwsY/isYqd/Gc3Q9Z3iQJMv8nQ P4Ywa+sa6i6A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,392,1583222400"; d="scan'208";a="410233894" X-Received: from shwdeopenpsi174.ccr.corp.intel.com ([10.239.157.39]) by orsmga004.jf.intel.com with ESMTP; 14 May 2020 14:52:50 -0700 From: "Xu, Wei6" To: devel@edk2.groups.io Cc: Michael D Kinney , Liming Gao , Sean Brogan Subject: [edk2-devel] [PATCH V3 3/5] FmpDevicePkg: Add FmpDependencyCheck library class and instances Date: Fri, 15 May 2020 05:52:30 +0800 Message-Id: <20200514215232.13372-4-wei6.xu@intel.com> In-Reply-To: <20200514215232.13372-1-wei6.xu@intel.com> References: <20200514215232.13372-1-wei6.xu@intel.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,wei6.xu@intel.com X-Gm-Message-State: 7OxR6Fk2ix8K0r70V2oVRxcZx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1589493173; bh=olFfF50KXAAju6uMmtTrNptRBxZb8k5+/LWmk8MuXxs=; h=Cc:Date:From:Reply-To:Subject:To; b=JkW2lALcSe/NFcP4UPHC1QWckqj2inwapc4pNcNL9lz6KcmVIw8UuOihC92vPqwJ0Tz pcJT4EtZ5HmdmiSapfs0qRcIuzLE5v9KoRWNxOcCZXMtCZXohlhAW1U/XrA2S/DJJqWUA j+s5dRcHEDYM7ZjcL5cbKESjQdIw2etZKpE= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2696 * This library class provides platform specific services to support dependency check during updating firmware image. Platform can perform dependency check in platform specific manner by implementing its own FmpDependencyCheckLib. * Add FmpDependencyCheck instance to provide a sample of dependency check. The sample instance only checks the dependency from capsule image. The dependency from other FMP instances isn't checked here. * Add NULL instance as an option to skip the dependency check. Cc: Michael D Kinney Cc: Liming Gao Cc: Sean Brogan Signed-off-by: Wei6 Xu --- FmpDevicePkg/FmpDevicePkg.dec | 4 + FmpDevicePkg/FmpDevicePkg.dsc | 3 + .../Include/Library/FmpDependencyCheckLib.h | 38 ++++ .../FmpDependencyCheckLib/FmpDependencyCheckLib.c | 196 +++++++++++++++++= ++++ .../FmpDependencyCheckLib.inf | 43 +++++ .../FmpDependencyCheckLib.uni | 13 ++ .../FmpDependencyCheckLibNull.c | 34 ++++ .../FmpDependencyCheckLibNull.inf | 30 ++++ .../FmpDependencyCheckLibNull.uni | 13 ++ 9 files changed, 374 insertions(+) create mode 100644 FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependenc= yCheckLib.c create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependenc= yCheckLib.inf create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependenc= yCheckLib.uni create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDepen= dencyCheckLibNull.c create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDepen= dencyCheckLibNull.inf create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDepen= dencyCheckLibNull.uni diff --git a/FmpDevicePkg/FmpDevicePkg.dec b/FmpDevicePkg/FmpDevicePkg.dec index 4947008346..871d5ce890 100644 --- a/FmpDevicePkg/FmpDevicePkg.dec +++ b/FmpDevicePkg/FmpDevicePkg.dec @@ -37,10 +37,14 @@ =20 ## @libraryclass Provides generic services to support capsule dependen= cy # expression evaluation. FmpDependencyLib|Include/Library/FmpDependencyLib.h =20 + ## @libraryclass Provides platform specific services to support depend= ency + # check during update of firmware image. + FmpDependencyCheckLib|Include/Library/FmpDependencyCheckLib.h + [LibraryClasses.Common.Private] ## @libraryclass Provides services to retrieve values from a capsule's= FMP # Payload Header. The structure is not included in the # library class. Instead, services are provided to ret= rieve # information from the FMP Payload Header. If informat= ion is diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc index 49c6ff3a30..7e80806171 100644 --- a/FmpDevicePkg/FmpDevicePkg.dsc +++ b/FmpDevicePkg/FmpDevicePkg.dsc @@ -61,10 +61,11 @@ FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAu= thenticationLibPkcs7.inf CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/C= apsuleUpdatePolicyLibNull.inf FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloa= dHeaderLibV1.inf FmpDeviceLib|FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf FmpDependencyLib|FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.= inf + FmpDependencyCheckLib|FmpDevicePkg/Library/FmpDependencyCheckLibNull/Fmp= DependencyCheckLibNull.inf TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplat= e.inf =20 [LibraryClasses.ARM, LibraryClasses.AARCH64] # # It is not possible to prevent the ARM compiler for generic intrinsic f= unctions. @@ -90,10 +91,12 @@ FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNu= ll.inf FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolic= yLibOnProtocol.inf FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf + FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf + FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull= .inf FmpDevicePkg/FmpDxe/FmpDxeLib.inf =20 # # Modules # diff --git a/FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h b/FmpDevi= cePkg/Include/Library/FmpDependencyCheckLib.h new file mode 100644 index 0000000000..ec380c4947 --- /dev/null +++ b/FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h @@ -0,0 +1,38 @@ +/** @file + Fmp Capsule Dependency check functions for Firmware Management Protocol = based + firmware updates. + + Copyright (c) 2020, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __FMP_DEPENDENCY_CHECK_LIB__ +#define __FMP_DEPENDENCY_CHECK_LIB__ + +#include +#include + +/** + Check dependency for firmware update. + + @param[in] ImageTypeId Image Type Id. + @param[in] Version New version. + @param[in] Dependencies Fmp dependency. + @param[in] DependenciesSize Size, in bytes, of the Fmp dependency. + + @retval TRUE Dependencies are satisfied. + @retval FALSE Dependencies are unsatisfied or dependency check fails. + +**/ +BOOLEAN +EFIAPI +CheckFmpDependency ( + IN EFI_GUID ImageTypeId, + IN UINT32 Version, + IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL + IN UINT32 DependenciesSize + ); + +#endif diff --git a/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckL= ib.c b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c new file mode 100644 index 0000000000..5e0241b259 --- /dev/null +++ b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c @@ -0,0 +1,196 @@ +/** @file + Provides FMP capsule dependency check services when updating the firmware + image of a FMP device. + + Copyright (c) 2020, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Check dependency for firmware update. + + @param[in] ImageTypeId Image Type Id. + @param[in] Version New version. + @param[in] Dependencies Fmp dependency. + @param[in] DependenciesSize Size, in bytes, of the Fmp dependency. + + @retval TRUE Dependencies are satisfied. + @retval FALSE Dependencies are unsatisfied or dependency check fails. + +**/ +BOOLEAN +EFIAPI +CheckFmpDependency ( + IN EFI_GUID ImageTypeId, + IN UINT32 Version, + IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL + IN UINT32 DependenciesSize + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN Index; + EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp; + UINTN ImageInfoSize; + UINT32 *DescriptorVer; + UINT8 FmpImageInfoCount; + UINTN *DescriptorSize; + UINT32 PackageVersion; + CHAR16 *PackageVersionName; + UINTN NumberOfFmpInstance; + EFI_FIRMWARE_IMAGE_DESCRIPTOR **FmpImageInfoBuf; + FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions; + UINTN FmpVersionsCount; + BOOLEAN IsSatisfied; + + FmpImageInfoBuf =3D NULL; + DescriptorVer =3D NULL; + DescriptorSize =3D NULL; + NumberOfFmpInstance =3D 0; + FmpVersions =3D NULL; + FmpVersionsCount =3D 0; + IsSatisfied =3D TRUE; + PackageVersionName =3D NULL; + + // + // Get ImageDescriptors of all FMP instances, and archive them for depen= dency evaluation. + // + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareManagementProtocolGuid, + NULL, + &NumberOfFmpInstance, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "CheckFmpDependency: Get Firmware Management Prot= ocol failed. (%r)", Status)); + goto cleanup; + } + + FmpImageInfoBuf =3D AllocateZeroPool (sizeof(EFI_FIRMWARE_IMAGE_DESCRIPT= OR *) * NumberOfFmpInstance); + if (FmpImageInfoBuf =3D=3D NULL) { + IsSatisfied =3D FALSE; + goto cleanup; + } + + DescriptorVer =3D AllocateZeroPool (sizeof(UINT32) * NumberOfFmpInstance= ); + if (DescriptorVer =3D=3D NULL ) { + IsSatisfied =3D FALSE; + goto cleanup; + } + + DescriptorSize =3D AllocateZeroPool (sizeof(UINTN) * NumberOfFmpInstance= ); + if (DescriptorSize =3D=3D NULL ) { + IsSatisfied =3D FALSE; + goto cleanup; + } + + FmpVersions =3D AllocateZeroPool (sizeof(FMP_DEPEX_CHECK_VERSION_DATA) *= NumberOfFmpInstance); + if (FmpVersions =3D=3D NULL) { + IsSatisfied =3D FALSE; + goto cleanup; + } + + for (Index =3D 0; Index < NumberOfFmpInstance; Index ++) { + Status =3D gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiFirmwareManagementProtocolGuid, + (VOID **) &Fmp + ); + if (EFI_ERROR(Status)) { + continue; + } + + ImageInfoSize =3D 0; + Status =3D Fmp->GetImageInfo ( + Fmp, + &ImageInfoSize, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL + ); + if (Status !=3D EFI_BUFFER_TOO_SMALL) { + continue; + } + + FmpImageInfoBuf[Index] =3D AllocateZeroPool (ImageInfoSize); + if (FmpImageInfoBuf[Index] =3D=3D NULL) { + continue; + } + + Status =3D Fmp->GetImageInfo ( + Fmp, + &ImageInfoSize, // ImageInfoSize + FmpImageInfoBuf[Index], // ImageInfo + &DescriptorVer[Index], // DescriptorVersion + &FmpImageInfoCount, // DescriptorCount + &DescriptorSize[Index], // DescriptorSize + &PackageVersion, // PackageVersion + &PackageVersionName // PackageVersionName + ); + if (EFI_ERROR(Status)) { + FreePool (FmpImageInfoBuf[Index]); + FmpImageInfoBuf[Index] =3D NULL; + continue; + } + + if (PackageVersionName !=3D NULL) { + FreePool (PackageVersionName); + PackageVersionName =3D NULL; + } + + CopyGuid (&FmpVersions[FmpVersionsCount].ImageTypeId, &FmpImageInfoBuf= [Index]->ImageTypeId); + FmpVersions[FmpVersionsCount].Version =3D FmpImageInfoBuf[Index]->Vers= ion; + FmpVersionsCount ++; + } + + // + // Evaluate firmware image's depex, against the version of other Fmp ins= tances. + // + if (Dependencies !=3D NULL) { + IsSatisfied =3D EvaluateDependency (Dependencies, DependenciesSize, Fm= pVersions, FmpVersionsCount); + } + + if (!IsSatisfied) { + DEBUG ((DEBUG_ERROR, "CheckFmpDependency: %g\'s dependency is not sati= sfied!\n", ImageTypeId)); + goto cleanup; + } + +cleanup: + if (FmpImageInfoBuf !=3D NULL) { + for (Index =3D 0; Index < NumberOfFmpInstance; Index ++) { + if (FmpImageInfoBuf[Index] !=3D NULL) { + FreePool (FmpImageInfoBuf[Index]); + } + } + FreePool (FmpImageInfoBuf); + } + + if (DescriptorVer !=3D NULL) { + FreePool (DescriptorVer); + } + + if (DescriptorSize !=3D NULL) { + FreePool (DescriptorSize); + } + + if (FmpVersions !=3D NULL) { + FreePool (FmpVersions); + } + + return IsSatisfied; +} diff --git a/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckL= ib.inf b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.i= nf new file mode 100644 index 0000000000..2050cc6490 --- /dev/null +++ b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf @@ -0,0 +1,43 @@ +## @file +# Provides FMP capsule dependency check services when updating the firmwa= re +# image of a FMP device. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D FmpDependencyCheckLib + MODULE_UNI_FILE =3D FmpDependencyCheckLib.uni + FILE_GUID =3D 8296D425-3095-4CFE-88D8-B0A44DB174A8 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D FmpDependencyCheckLib|DXE_DRIVER UEFI_DRIVER UEFI_AP= PLICATION + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 ARM AARCH64 +# + +[Sources] + FmpDependencyCheckLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + FmpDevicePkg/FmpDevicePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + FmpDependencyLib + MemoryAllocationLib + UefiLib + UefiBootServicesTableLib + +[Protocols] + gEfiFirmwareManagementProtocolGuid ## CONSUMES diff --git a/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckL= ib.uni b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.u= ni new file mode 100644 index 0000000000..c6369e2277 --- /dev/null +++ b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.uni @@ -0,0 +1,13 @@ +// /** @file +// Provides FMP capsule dependency check services when updating the firmwa= re +// image of a FMP device. +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "FMP Dependency Check Lib" + +#string STR_MODULE_DESCRIPTION #language en-US "Provides FMP capsule dep= endency check services when updating the firmware image of a FMP device." diff --git a/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCh= eckLibNull.c b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependency= CheckLibNull.c new file mode 100644 index 0000000000..55e9af2290 --- /dev/null +++ b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibN= ull.c @@ -0,0 +1,34 @@ +/** @file + Null instance of FmpDependencyCheckLib. + + Copyright (c) 2020, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include + +/** + Check dependency for firmware update. + + @param[in] ImageTypeId Image Type Id. + @param[in] Version New version. + @param[in] Dependencies Fmp dependency. + @param[in] DependenciesSize Size, in bytes, of the Fmp dependency. + + @retval TRUE Dependencies are satisfied. + @retval FALSE Dependencies are unsatisfied or dependency check fails. + +**/ +BOOLEAN +EFIAPI +CheckFmpDependency ( + IN EFI_GUID ImageTypeId, + IN UINT32 Version, + IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL + IN UINT32 DependenciesSize + ) +{ + return TRUE; +} diff --git a/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCh= eckLibNull.inf b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependen= cyCheckLibNull.inf new file mode 100644 index 0000000000..5794d89191 --- /dev/null +++ b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibN= ull.inf @@ -0,0 +1,30 @@ +## @file +# Null instance of FmpDependencyCheckLib as an option to skip the depende= ncy +# check when updating the firmware image of a FMP device. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D FmpDependencyCheckLibNull + MODULE_UNI_FILE =3D FmpDependencyCheckLibNull.uni + FILE_GUID =3D D63F3166-9CBC-4AC2-8F23-8818E42EA2BD + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D FmpDependencyCheckLib|DXE_DRIVER UEFI_DRIVER UEFI_AP= PLICATION + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 ARM AARCH64 +# + +[Sources] + FmpDependencyCheckLibNull.c + +[Packages] + MdePkg/MdePkg.dec + FmpDevicePkg/FmpDevicePkg.dec diff --git a/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCh= eckLibNull.uni b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependen= cyCheckLibNull.uni new file mode 100644 index 0000000000..7942d08f76 --- /dev/null +++ b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibN= ull.uni @@ -0,0 +1,13 @@ +// /** @file +// Null instance of FmpDependencyCheckLib as an option to skip the depende= ncy +// check when updating the firmware image of a FMP device. +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "FMP Dependency Check Lib= rary NULL instance" + +#string STR_MODULE_DESCRIPTION #language en-US "Null instance of FmpDepe= ndencyCheckLib as an option to skip the dependency check when updating the = firmware image of a FMP device." --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#59605): https://edk2.groups.io/g/devel/message/59605 Mute This Topic: https://groups.io/mt/74215663/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Tue Apr 16 13:31:03 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+59606+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+59606+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1589493176; cv=none; d=zohomail.com; s=zohoarc; b=S15LFoFniSis8i1/GxdFSkMIx3c9UdcqnVSzuVJfl0h3IjnE4jv3vphacFgLJfXxxmAw97nuOerufRSWp72+6TDKaCRc7dyvXFrCLMp22jpJWBxCm8+zuvI0y5ev0G9UMb8QmGnt761Gy9+ObWlAXTzaFXgjSmebIoSBsgoHggE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589493176; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=doPqb/l9wwwb9c5lfXXYriVmxxOlEU8sTLvQRsaLgMw=; b=I0FVycfUYc2HjhU1Eg6ELyX11q3c5EmpT3VQZ0l3JB7OV3Mnd38+NCFZSlnPktYQM8COvEzxEhJV2GPKfI8Uyx4vGaEkoVgCmDA7CFr0IoR1EbqMhp45vlECqh59j/EoPjjZw3nzvU2lSxza2xPY4GuoBkRMWPXQRN9ysZ27/Ro= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+59606+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1589493176911856.8534845543663; Thu, 14 May 2020 14:52:56 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 1ZDhYY1788612x8xs3et9DuG; Thu, 14 May 2020 14:52:55 -0700 X-Received: from mga04.intel.com (mga04.intel.com []) by mx.groups.io with SMTP id smtpd.web11.1970.1589493168169412090 for ; Thu, 14 May 2020 14:52:55 -0700 IronPort-SDR: kiSQPqRsjoOwKwOmS1VdrCiSVtuUpYcbn2FUyEfLd2PI2nh/wDDpOc1HVsT0lA2qbN7k9gkXya 27fi+7xGycDQ== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 May 2020 14:52:54 -0700 IronPort-SDR: aJoD2H/EzeNuEPD3e5mi7H7Jr+FtRG5vwhjqVbUk+Ijgy91r8yS6lVssjL5N74YUKQj8lrJTyd 1M4va+HucCLg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,392,1583222400"; d="scan'208";a="410233922" X-Received: from shwdeopenpsi174.ccr.corp.intel.com ([10.239.157.39]) by orsmga004.jf.intel.com with ESMTP; 14 May 2020 14:52:53 -0700 From: "Xu, Wei6" To: devel@edk2.groups.io Cc: Michael D Kinney , Liming Gao , Sean Brogan Subject: [edk2-devel] [PATCH V3 4/5] FmpDevicePkg: Add FmpDependencyDevice library class and NULL instance Date: Fri, 15 May 2020 05:52:31 +0800 Message-Id: <20200514215232.13372-5-wei6.xu@intel.com> In-Reply-To: <20200514215232.13372-1-wei6.xu@intel.com> References: <20200514215232.13372-1-wei6.xu@intel.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,wei6.xu@intel.com X-Gm-Message-State: KCU9zGEuWyRHwUXWh88Yd4ibx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1589493175; bh=A6ufQvvNqEenbi1ZFz6WcAUlnnXPiSi/dbohX4lCf+I=; h=Cc:Date:From:Reply-To:Subject:To; b=Td2vyXCH/qhKQ3a3QHaWcgMgpjBw64iMnY2l1Yk2x2iy1QlRAx9YtkqEvCXAejDohLY YjzyLDl/Qpp/Kb5dsu9Oa9fiw/zc7Q6f15yGE9IPnQmL9HQnJ+6xHBCFRf1NatH0YMxMI gn0h3aWJWfj83f0Cvfi4FAviBlyuPYCrMbY= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2696 This library provides firmware device specific services to support saving dependency to firmware device and getting dependency from firmware device. Cc: Michael D Kinney Cc: Liming Gao Cc: Sean Brogan Signed-off-by: Wei6 Xu --- FmpDevicePkg/FmpDevicePkg.dec | 5 +++ FmpDevicePkg/FmpDevicePkg.dsc | 2 + .../Include/Library/FmpDependencyDeviceLib.h | 51 ++++++++++++++++++= ++++ .../FmpDependencyDeviceLib.c | 50 ++++++++++++++++++= +++ .../FmpDependencyDeviceLibNull.inf | 29 ++++++++++++ .../FmpDependencyDeviceLibNull.uni | 12 +++++ 6 files changed, 149 insertions(+) create mode 100644 FmpDevicePkg/Include/Library/FmpDependencyDeviceLib.h create mode 100644 FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDepe= ndencyDeviceLib.c create mode 100644 FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDepe= ndencyDeviceLibNull.inf create mode 100644 FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDepe= ndencyDeviceLibNull.uni diff --git a/FmpDevicePkg/FmpDevicePkg.dec b/FmpDevicePkg/FmpDevicePkg.dec index 871d5ce890..cab63f5a47 100644 --- a/FmpDevicePkg/FmpDevicePkg.dec +++ b/FmpDevicePkg/FmpDevicePkg.dec @@ -41,10 +41,15 @@ =20 ## @libraryclass Provides platform specific services to support depend= ency # check during update of firmware image. FmpDependencyCheckLib|Include/Library/FmpDependencyCheckLib.h =20 + ## @libraryclass Provides firmware device specific services to support + # saving dependency to firmware device and getting depe= ndency + # from firmware device. + FmpDependencyDeviceLib|Include/Library/FmpDependencyDeviceLib.h + [LibraryClasses.Common.Private] ## @libraryclass Provides services to retrieve values from a capsule's= FMP # Payload Header. The structure is not included in the # library class. Instead, services are provided to ret= rieve # information from the FMP Payload Header. If informat= ion is diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc index 7e80806171..bdb73f2828 100644 --- a/FmpDevicePkg/FmpDevicePkg.dsc +++ b/FmpDevicePkg/FmpDevicePkg.dsc @@ -62,10 +62,11 @@ CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/C= apsuleUpdatePolicyLibNull.inf FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloa= dHeaderLibV1.inf FmpDeviceLib|FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf FmpDependencyLib|FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.= inf FmpDependencyCheckLib|FmpDevicePkg/Library/FmpDependencyCheckLibNull/Fmp= DependencyCheckLibNull.inf + FmpDependencyDeviceLib|FmpDevicePkg/Library/FmpDependencyDeviceLibNull/F= mpDependencyDeviceLibNull.inf TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplat= e.inf =20 [LibraryClasses.ARM, LibraryClasses.AARCH64] # # It is not possible to prevent the ARM compiler for generic intrinsic f= unctions. @@ -93,10 +94,11 @@ FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull= .inf + FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNu= ll.inf FmpDevicePkg/FmpDxe/FmpDxeLib.inf =20 # # Modules # diff --git a/FmpDevicePkg/Include/Library/FmpDependencyDeviceLib.h b/FmpDev= icePkg/Include/Library/FmpDependencyDeviceLib.h new file mode 100644 index 0000000000..4351173b7e --- /dev/null +++ b/FmpDevicePkg/Include/Library/FmpDependencyDeviceLib.h @@ -0,0 +1,51 @@ +/** @file + Provides firmware device specific services to support saving dependency = to + firmware device and getting dependency from firmware device. + + Copyright (c) 2020, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __FMP_DEPENDENCY_DEVICE_LIB__ +#define __FMP_DEPENDENCY_DEVICE_LIB__ + +#include +#include + +/** + Save dependency to Fmp device. + + @param[in] Depex Fmp dependency. + @param[in] DepexSize Size, in bytes, of the Fmp dependency. + + @retval EFI_SUCCESS Save Fmp dependency succeeds. + @retval EFI_UNSUPPORTED Save Fmp dependency is not supported. + @retval Others Save Fmp dependency fails. + +**/ +EFI_STATUS +EFIAPI +SaveFmpDependency ( + IN EFI_FIRMWARE_IMAGE_DEP *Depex, + IN UINT32 DepexSize + ); + +/** + Get dependency from the Fmp device. + This caller is responsible for freeing the dependency buffer. + + @param[out] DepexSize Size, in bytes, of the dependency. + + @retval The pointer to dependency. + @retval NULL + +**/ +EFI_FIRMWARE_IMAGE_DEP* +EFIAPI +GetFmpDependency ( + OUT UINT32 *DepexSize + ); + +#endif diff --git a/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyD= eviceLib.c b/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyD= eviceLib.c new file mode 100644 index 0000000000..0839681430 --- /dev/null +++ b/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLi= b.c @@ -0,0 +1,50 @@ +/** @file + Null instance of FmpDependencyDeviceLib. + + Copyright (c) 2020, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include + +/** + Save dependency to Fmp device. + + @param[in] Depex Fmp dependency. + @param[in] DepexSize Size, in bytes, of the Fmp dependency. + + @retval EFI_SUCCESS Save Fmp dependency succeeds. + @retval EFI_UNSUPPORTED Save Fmp dependency is not supported. + @retval Others Save Fmp dependency fails. + +**/ +EFI_STATUS +EFIAPI +SaveFmpDependency ( + IN EFI_FIRMWARE_IMAGE_DEP *Depex, + IN UINT32 DepexSize + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Get dependency from the Fmp device. + This caller is responsible for freeing the dependency buffer. + + @param[out] DepexSize Size, in bytes, of the dependency. + + @retval The pointer to dependency. + @retval NULL + +**/ +EFI_FIRMWARE_IMAGE_DEP* +EFIAPI +GetFmpDependency ( + OUT UINT32 *DepexSize + ) +{ + return NULL; +} diff --git a/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyD= eviceLibNull.inf b/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDepen= dencyDeviceLibNull.inf new file mode 100644 index 0000000000..d318cc9a67 --- /dev/null +++ b/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLi= bNull.inf @@ -0,0 +1,29 @@ +## @file +# Fmp Dependency Device Library Null instance. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D FmpDependencyDeviceLibNull + MODULE_UNI_FILE =3D FmpDependencyDeviceLibNull.uni + FILE_GUID =3D 05BE67B1-0748-4022-97E6-7C0D2F992AA6 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D FmpDependencyDeviceLib|DXE_DRIVER UEFI_DRIVER + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 ARM AARCH64 +# + +[Sources] + FmpDependencyDeviceLib.c + +[Packages] + MdePkg/MdePkg.dec + FmpDevicePkg/FmpDevicePkg.dec diff --git a/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyD= eviceLibNull.uni b/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDepen= dencyDeviceLibNull.uni new file mode 100644 index 0000000000..730ff65cbd --- /dev/null +++ b/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLi= bNull.uni @@ -0,0 +1,12 @@ +// /** @file +// Fmp Dependency Device Library Null instance. +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Fmp Dependency Device Li= brary Null instance." + +#string STR_MODULE_DESCRIPTION #language en-US "Null instance that does = not support saving and getting dependency for Fmp device." --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#59606): https://edk2.groups.io/g/devel/message/59606 Mute This Topic: https://groups.io/mt/74215664/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Tue Apr 16 13:31:03 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+59607+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+59607+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1589493180; cv=none; d=zohomail.com; s=zohoarc; b=iV3OesQDQSP3z6gnEwsMG4cGXwkMSOHjGHSpSU6YSwbemfvIX3qwU2RNd4ePNCrQDz5xD0HJ12zEZx+h30D3N4k5BrPD3WVXfk+LTqpK08SxKeDV/y2VwVOU1R+wjLkuJr2wSSZ3VUHJ1LrEBuWjBh8yAKeFBTluaCDvG7+q94w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589493180; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=AUkkz54+YDNuet/UzHkedhoKMqdG59GfFjwH6p8gRcY=; b=iVO60xGlQmX4Qk+knNZvrNCQn2eSKP4lqAw9tL4Mc0b2kkaZz7LoYA1PeG99YjnjCUvOmgCMfkDjCdk5MlpwcU36yJph32+uFGgZ/telROWERbPF/+9162/HrKM3WEybxtgDOuh6hwBO3WYEgrlpiY2NEWZOAHXo9NTY4NMZzsE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+59607+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1589493180009841.2942102013556; Thu, 14 May 2020 14:53:00 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id P64qYY1788612xdYv40kHUh0; Thu, 14 May 2020 14:52:59 -0700 X-Received: from mga04.intel.com (mga04.intel.com []) by mx.groups.io with SMTP id smtpd.web11.1970.1589493168169412090 for ; Thu, 14 May 2020 14:52:59 -0700 IronPort-SDR: yAN2X+6nWQMvKKQ7XkkEfoGRdTbohRBSS0eROmHZFpKF9B72sZF3JStx0XYA6aAZpi/ICBn4+6 cl9uGSXqh+9A== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 May 2020 14:52:58 -0700 IronPort-SDR: Jfckz1GVTjejb68b3Tz4NHqjUe66rtjUqwmvXHUIj9aow8Z1d+HWfUfbyZG/0xktlrVpFvsIYV 7/436uzD6Xjw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,392,1583222400"; d="scan'208";a="410233937" X-Received: from shwdeopenpsi174.ccr.corp.intel.com ([10.239.157.39]) by orsmga004.jf.intel.com with ESMTP; 14 May 2020 14:52:55 -0700 From: "Xu, Wei6" To: devel@edk2.groups.io Cc: Michael D Kinney , Liming Gao , Sean Brogan Subject: [edk2-devel] [PATCH V3 5/5] FmpDevicePkg/FmpDxe: Use new Fmp dependency libraries Date: Fri, 15 May 2020 05:52:32 +0800 Message-Id: <20200514215232.13372-6-wei6.xu@intel.com> In-Reply-To: <20200514215232.13372-1-wei6.xu@intel.com> References: <20200514215232.13372-1-wei6.xu@intel.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,wei6.xu@intel.com X-Gm-Message-State: 9iZRWbAKuOa2pAcej6nMNfMux1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1589493179; bh=3eBsHmpz2bGNLvRSaAxRwy4hxQsDESq/1h/yAYFLqCw=; h=Cc:Date:From:Reply-To:Subject:To; b=ZZjDYkzg4ywBPBiC/gki137pRs43qf5cUYZOeKYteHkWqgE/epajzflXNwPVs4B4Osf 483DqdURyETxT8TvO6BZBSi+RVLDzCftiIToyIh8OATZbC9W1hJqVS6KBDdsP4GMCygll cAvzq4WEOoRQVIuqROVCdf1lUAmX/XGREEE= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2696 Remove the orginal Fmp Capsule Dependency implement, and use new FmpDependencyLib, FmpDependencyCheckLib and FmpDependencyDeviceLib APIs instead. A platform can perform the dependency check in a platform specific manner by implementing its own FmpDependencyCheckLib. Cc: Michael D Kinney Cc: Liming Gao Cc: Sean Brogan Signed-off-by: Wei6 Xu --- FmpDevicePkg/FmpDxe/Dependency.c | 679 ----------------------------------= ---- FmpDevicePkg/FmpDxe/Dependency.h | 63 ---- FmpDevicePkg/FmpDxe/FmpDxe.c | 256 +++----------- FmpDevicePkg/FmpDxe/FmpDxe.h | 4 + FmpDevicePkg/FmpDxe/FmpDxe.inf | 5 +- FmpDevicePkg/FmpDxe/FmpDxeLib.inf | 5 +- 6 files changed, 64 insertions(+), 948 deletions(-) delete mode 100644 FmpDevicePkg/FmpDxe/Dependency.c delete mode 100644 FmpDevicePkg/FmpDxe/Dependency.h diff --git a/FmpDevicePkg/FmpDxe/Dependency.c b/FmpDevicePkg/FmpDxe/Depende= ncy.c deleted file mode 100644 index 65c23989c6..0000000000 --- a/FmpDevicePkg/FmpDxe/Dependency.c +++ /dev/null @@ -1,679 +0,0 @@ -/** @file - Supports Capsule Dependency Expression. - - Copyright (c) 2020, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ -#include "FmpDxe.h" -#include "Dependency.h" - -// -// Define the initial size of the dependency expression evaluation stack -// -#define DEPEX_STACK_SIZE_INCREMENT 0x1000 - -// -// Type of stack element -// -typedef enum { - BooleanType, - VersionType -} ELEMENT_TYPE; - -// -// Value of stack element -// -typedef union { - BOOLEAN Boolean; - UINT32 Version; -} ELEMENT_VALUE; - -// -// Stack element used to evaluate dependency expressions -// -typedef struct { - ELEMENT_VALUE Value; - ELEMENT_TYPE Type; -} DEPEX_ELEMENT; - -// -// Global variable used to support dependency evaluation -// -UINTN mNumberOfFmpInstance =3D 0; -EFI_FIRMWARE_IMAGE_DESCRIPTOR **mFmpImageInfoBuf =3D NULL; - -// -// Indicates the status of dependency check, default value is DEPENDENCIES= _SATISFIED. -// -UINT8 mDependenciesCheckStatus =3D DEPENDENCIES_SATISFIED; - -// -// Global stack used to evaluate dependency expressions -// -DEPEX_ELEMENT *mDepexEvaluationStack =3D NULL; -DEPEX_ELEMENT *mDepexEvaluationStackEnd =3D NULL; -DEPEX_ELEMENT *mDepexEvaluationStackPointer =3D NULL; - -/** - Grow size of the Depex stack - - @retval EFI_SUCCESS Stack successfully growed. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow = the stack. - -**/ -EFI_STATUS -GrowDepexStack ( - VOID - ) -{ - DEPEX_ELEMENT *NewStack; - UINTN Size; - - Size =3D DEPEX_STACK_SIZE_INCREMENT; - if (mDepexEvaluationStack !=3D NULL) { - Size =3D Size + (mDepexEvaluationStackEnd - mDepexEvaluationStack); - } - - NewStack =3D AllocatePool (Size * sizeof (DEPEX_ELEMENT)); - if (NewStack =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - if (mDepexEvaluationStack !=3D NULL) { - // - // Copy to Old Stack to the New Stack - // - CopyMem ( - NewStack, - mDepexEvaluationStack, - (mDepexEvaluationStackEnd - mDepexEvaluationStack) * sizeof (DEPEX_E= LEMENT) - ); - - // - // Free The Old Stack - // - FreePool (mDepexEvaluationStack); - } - - // - // Make the Stack pointer point to the old data in the new stack - // - mDepexEvaluationStackPointer =3D NewStack + (mDepexEvaluationStackPointe= r - mDepexEvaluationStack); - mDepexEvaluationStack =3D NewStack; - mDepexEvaluationStackEnd =3D NewStack + Size; - - return EFI_SUCCESS; -} - -/** - Push an element onto the Stack. - - @param[in] Value Value to push. - @param[in] Type Element Type - - @retval EFI_SUCCESS The value was pushed onto the stack. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. - @retval EFI_INVALID_PARAMETER Wrong stack element type. - -**/ -EFI_STATUS -Push ( - IN UINT32 Value, - IN UINTN Type - ) -{ - EFI_STATUS Status; - DEPEX_ELEMENT Element; - - // - // Check Type - // - if (Type !=3D BooleanType && Type !=3D VersionType) { - return EFI_INVALID_PARAMETER; - } - - // - // Check for a stack overflow condition - // - if (mDepexEvaluationStackPointer =3D=3D mDepexEvaluationStackEnd) { - // - // Grow the stack - // - Status =3D GrowDepexStack (); - if (EFI_ERROR (Status)) { - return Status; - } - } - - Element.Value.Version =3D Value; - Element.Type =3D Type; - - // - // Push the item onto the stack - // - *mDepexEvaluationStackPointer =3D Element; - mDepexEvaluationStackPointer++; - - return EFI_SUCCESS; -} - - -/** - Pop an element from the stack. - - @param[out] Element Element to pop. - @param[in] Type Type of element. - - @retval EFI_SUCCESS The value was popped onto the stack. - @retval EFI_ACCESS_DENIED The pop operation underflowed the stack. - @retval EFI_INVALID_PARAMETER Type is mismatched. - -**/ -EFI_STATUS -Pop ( - OUT DEPEX_ELEMENT *Element, - IN ELEMENT_TYPE Type - ) -{ - // - // Check for a stack underflow condition - // - if (mDepexEvaluationStackPointer =3D=3D mDepexEvaluationStack) { - return EFI_ACCESS_DENIED; - } - - // - // Pop the item off the stack - // - mDepexEvaluationStackPointer--; - *Element =3D *mDepexEvaluationStackPointer; - if ((*Element).Type !=3D Type) { - return EFI_INVALID_PARAMETER; - } - return EFI_SUCCESS; -} - -/** - Evaluate the dependencies. - - @param[in] Dependencies Dependency expressions. - @param[in] DependenciesSize Size of Dependency expressions. - - @retval TRUE Dependency expressions evaluate to TRUE. - @retval FALSE Dependency expressions evaluate to FALSE. - -**/ -BOOLEAN -EvaluateDependencies ( - IN CONST EFI_FIRMWARE_IMAGE_DEP * Dependencies, - IN CONST UINTN DependenciesSize - ) -{ - EFI_STATUS Status; - UINT8 *Iterator; - UINT8 Index; - DEPEX_ELEMENT Element1; - DEPEX_ELEMENT Element2; - GUID ImageTypeId; - UINT32 Version; - - if (Dependencies =3D=3D NULL || DependenciesSize =3D=3D 0) { - return FALSE; - } - - // - // Clean out memory leaks in Depex Boolean stack. Leaks are only caused = by - // incorrectly formed DEPEX expressions - // - mDepexEvaluationStackPointer =3D mDepexEvaluationStack; - - Iterator =3D (UINT8 *) Dependencies->Dependencies; - while (Iterator < (UINT8 *) Dependencies->Dependencies + DependenciesSiz= e) { - switch (*Iterator) - { - case EFI_FMP_DEP_PUSH_GUID: - if (Iterator + sizeof (EFI_GUID) >=3D (UINT8 *) Dependencies->Depend= encies + DependenciesSize) { - Status =3D EFI_INVALID_PARAMETER; - goto Error; - } - - CopyGuid (&ImageTypeId, (EFI_GUID *) (Iterator + 1)); - Iterator =3D Iterator + sizeof (EFI_GUID); - - for (Index =3D 0; Index < mNumberOfFmpInstance; Index ++){ - if (mFmpImageInfoBuf[Index] =3D=3D NULL) { - continue; - } - if(CompareGuid (&mFmpImageInfoBuf[Index]->ImageTypeId, &ImageTypeI= d)){ - Status =3D Push (mFmpImageInfoBuf[Index]->Version, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - } - } - if (Index =3D=3D mNumberOfFmpInstance) { - Status =3D EFI_NOT_FOUND; - goto Error; - } - break; - case EFI_FMP_DEP_PUSH_VERSION: - if (Iterator + sizeof (UINT32) >=3D (UINT8 *) Dependencies->Dependen= cies + DependenciesSize ) { - Status =3D EFI_INVALID_PARAMETER; - goto Error; - } - - Version =3D *(UINT32 *) (Iterator + 1); - Status =3D Push (Version, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Iterator =3D Iterator + sizeof (UINT32); - break; - case EFI_FMP_DEP_VERSION_STR: - Iterator +=3D AsciiStrnLenS ((CHAR8 *) Iterator, DependenciesSize - = (Iterator - Dependencies->Dependencies)); - break; - case EFI_FMP_DEP_AND: - Status =3D Pop (&Element1, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D Pop (&Element2, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D Push (Element1.Value.Boolean & Element2.Value.Boolean, Bo= oleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_OR: - Status =3D Pop (&Element1, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D Pop(&Element2, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D Push (Element1.Value.Boolean | Element2.Value.Boolean, Bo= oleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_NOT: - Status =3D Pop (&Element1, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D Push (!(Element1.Value.Boolean), BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_TRUE: - Status =3D Push (TRUE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_FALSE: - Status =3D Push (FALSE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_EQ: - Status =3D Pop (&Element1, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D Pop (&Element2, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D (Element1.Value.Version =3D=3D Element2.Value.Version) ? = Push (TRUE, BooleanType) : Push (FALSE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_GT: - Status =3D Pop (&Element1, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D Pop (&Element2, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D (Element1.Value.Version > Element2.Value.Version) ? Push= (TRUE, BooleanType) : Push (FALSE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_GTE: - Status =3D Pop (&Element1, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D Pop (&Element2, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D (Element1.Value.Version >=3D Element2.Value.Version) ? Pu= sh (TRUE, BooleanType) : Push (FALSE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_LT: - Status =3D Pop (&Element1, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D Pop (&Element2, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D (Element1.Value.Version < Element2.Value.Version) ? Push= (TRUE, BooleanType) : Push (FALSE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_LTE: - Status =3D Pop (&Element1, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D Pop (&Element2, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status =3D (Element1.Value.Version <=3D Element2.Value.Version) ? Pu= sh (TRUE, BooleanType) : Push (FALSE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_END: - Status =3D Pop (&Element1, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - return Element1.Value.Boolean; - default: - Status =3D EFI_INVALID_PARAMETER; - goto Error; - } - Iterator++; - } - -Error: - - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): EvaluateDependencies() - RESULT =3D FA= LSE (Status =3D %r)\n", mImageIdName, Status)); - return FALSE; -} - -/** - Validate the dependency expression and output its size. - - @param[in] ImageDepex Pointer to the EFI_FIRMWARE_IMAGE_DEP. - @param[in] MaxDepexSize Max size of the dependency. - @param[out] DepexSize Size of dependency. - - @retval TRUE The capsule is valid. - @retval FALSE The capsule is invalid. - -**/ -BOOLEAN -ValidateImageDepex ( - IN EFI_FIRMWARE_IMAGE_DEP *ImageDepex, - IN CONST UINTN MaxDepexSize, - OUT UINT32 *DepexSize - ) -{ - UINT8 *Depex; - - *DepexSize =3D 0; - Depex =3D ImageDepex->Dependencies; - while (Depex < ImageDepex->Dependencies + MaxDepexSize) { - switch (*Depex) - { - case EFI_FMP_DEP_PUSH_GUID: - Depex +=3D sizeof (EFI_GUID) + 1; - break; - case EFI_FMP_DEP_PUSH_VERSION: - Depex +=3D sizeof (UINT32) + 1; - break; - case EFI_FMP_DEP_VERSION_STR: - Depex +=3D AsciiStrnLenS ((CHAR8 *) Depex, ImageDepex->Dependencies = + MaxDepexSize - Depex) + 1; - break; - case EFI_FMP_DEP_AND: - case EFI_FMP_DEP_OR: - case EFI_FMP_DEP_NOT: - case EFI_FMP_DEP_TRUE: - case EFI_FMP_DEP_FALSE: - case EFI_FMP_DEP_EQ: - case EFI_FMP_DEP_GT: - case EFI_FMP_DEP_GTE: - case EFI_FMP_DEP_LT: - case EFI_FMP_DEP_LTE: - Depex +=3D 1; - break; - case EFI_FMP_DEP_END: - Depex +=3D 1; - *DepexSize =3D (UINT32)(Depex - ImageDepex->Dependencies); - return TRUE; - default: - return FALSE; - } - } - - return FALSE; -} - - -/** - Get the size of dependencies. Assume the dependencies is validated before - calling this function. - - @param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP. - - @retval The size of dependencies. - -**/ -UINTN -GetDepexSize ( - IN CONST EFI_FIRMWARE_IMAGE_DEP *Dependencies - ) -{ - UINTN Index; - - if (Dependencies =3D=3D NULL) { - return 0; - } - - Index =3D 0; - while (Dependencies->Dependencies[Index] !=3D EFI_FMP_DEP_END) { - Index ++; - } - - return Index + 1; -} - -/** - Check dependency for firmware update. - - @param[in] ImageTypeId Image Type Id. - @param[in] Version New version. - @param[in] Dependencies The dependencies. - @param[in] DependenciesSize Size of the dependencies - @param[out] IsSatisfied Indicate the dependencies is satisfied = or not. - - @retval EFI_SUCCESS Dependency Evaluation is successful. - @retval Others Dependency Evaluation fails with unexpe= cted error. - -**/ -EFI_STATUS -EvaluateImageDependencies ( - IN CONST EFI_GUID ImageTypeId, - IN CONST UINT32 Version, - IN CONST EFI_FIRMWARE_IMAGE_DEP *Dependencies, - IN CONST UINT32 DependenciesSize, - OUT BOOLEAN *IsSatisfied - ) -{ - EFI_STATUS Status; - EFI_HANDLE *HandleBuffer; - UINTN Index; - EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp; - UINTN ImageInfoSize; - UINT32 FmpImageInfoDescriptorVer; - UINT8 FmpImageInfoCount; - UINTN DescriptorSize; - UINT32 PackageVersion; - CHAR16 *PackageVersionName; - UINTN DepexSize; - - *IsSatisfied =3D TRUE; - PackageVersionName =3D NULL; - - // - // Get ImageDescriptors of all FMP instances, and archive them for depex= evaluation. - // - Status =3D gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiFirmwareManagementProtocolGuid, - NULL, - &mNumberOfFmpInstance, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - - mFmpImageInfoBuf =3D AllocateZeroPool (sizeof(EFI_FIRMWARE_IMAGE_DESCRIP= TOR *) * mNumberOfFmpInstance); - if (mFmpImageInfoBuf =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - for (Index =3D 0; Index < mNumberOfFmpInstance; Index ++) { - Status =3D gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiFirmwareManagementProtocolGuid, - (VOID **) &Fmp - ); - if (EFI_ERROR(Status)) { - continue; - } - - ImageInfoSize =3D 0; - Status =3D Fmp->GetImageInfo ( - Fmp, - &ImageInfoSize, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - ); - if (Status !=3D EFI_BUFFER_TOO_SMALL) { - continue; - } - - mFmpImageInfoBuf[Index] =3D AllocateZeroPool (ImageInfoSize); - if (mFmpImageInfoBuf[Index] =3D=3D NULL) { - continue; - } - - Status =3D Fmp->GetImageInfo ( - Fmp, - &ImageInfoSize, // ImageInfoSize - mFmpImageInfoBuf[Index], // ImageInfo - &FmpImageInfoDescriptorVer, // DescriptorVersion - &FmpImageInfoCount, // DescriptorCount - &DescriptorSize, // DescriptorSize - &PackageVersion, // PackageVersion - &PackageVersionName // PackageVersionName - ); - if (EFI_ERROR(Status)) { - FreePool (mFmpImageInfoBuf[Index]); - mFmpImageInfoBuf[Index] =3D NULL; - continue; - } - - if (PackageVersionName !=3D NULL) { - FreePool (PackageVersionName); - PackageVersionName =3D NULL; - } - } - - // - // Step 1 - Evaluate firmware image's depex, against the version of othe= r Fmp instances. - // - if (Dependencies !=3D NULL) { - *IsSatisfied =3D EvaluateDependencies (Dependencies, DependenciesSize); - } - - if (!*IsSatisfied) { - goto cleanup; - } - - // - // Step 2 - Evaluate the depex of all other Fmp instances, against the n= ew version in - // the firmware image. - // - - // - // Update the new version to mFmpImageInfoBuf. - // - for (Index =3D 0; Index < mNumberOfFmpInstance; Index ++) { - if (mFmpImageInfoBuf[Index] !=3D NULL) { - if (CompareGuid (&ImageTypeId, &mFmpImageInfoBuf[Index]->ImageTypeId= )) { - mFmpImageInfoBuf[Index]->Version =3D Version; - break; - } - } - } - - // - // Evaluate the Dependencies one by one. - // - for (Index =3D 0; Index < mNumberOfFmpInstance; Index ++) { - if (mFmpImageInfoBuf[Index] !=3D NULL) { - // - // Skip the Fmp instance to be "SetImage". - // - if (CompareGuid (&ImageTypeId, &mFmpImageInfoBuf[Index]->ImageTypeId= )) { - continue; - } - if ((mFmpImageInfoBuf[Index]->AttributesSupported & IMAGE_ATTRIBUTE_= DEPENDENCY) && - mFmpImageInfoBuf[Index]->Dependencies !=3D NULL) { - // - // Get the size of depex. - // Assume that the dependencies in EFI_FIRMWARE_IMAGE_DESCRIPTOR i= s validated when PopulateDescriptor(). - // - DepexSize =3D GetDepexSize (mFmpImageInfoBuf[Index]->Dependencies); - if (DepexSize > 0) { - *IsSatisfied =3D EvaluateDependencies (mFmpImageInfoBuf[Index]->= Dependencies, DepexSize); - if (!*IsSatisfied) { - break; - } - } - } - } - } - -cleanup: - if (mFmpImageInfoBuf !=3D NULL) { - for (Index =3D 0; Index < mNumberOfFmpInstance; Index ++) { - if (mFmpImageInfoBuf[Index] !=3D NULL) { - FreePool (mFmpImageInfoBuf[Index]); - } - } - FreePool (mFmpImageInfoBuf); - } - - return EFI_SUCCESS; -} diff --git a/FmpDevicePkg/FmpDxe/Dependency.h b/FmpDevicePkg/FmpDxe/Depende= ncy.h deleted file mode 100644 index badd2542d6..0000000000 --- a/FmpDevicePkg/FmpDxe/Dependency.h +++ /dev/null @@ -1,63 +0,0 @@ -/** @file - Fmp Capsule Dependency support functions for Firmware Management Protoco= l based - firmware updates. - - Copyright (c) 2020, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __DEPENDENCY_H__ -#define __DEPENDENCY_H__ - -#include -#include - -#define DEPENDENCIES_SATISFIED 0 -#define DEPENDENCIES_UNSATISFIED 1 -#define DEPENDENCIES_INVALID 2 - -extern UINT8 mDependenciesCheckStatus; - -/** - Validate the dependency expression and output its size. - - @param[in] ImageDepex Pointer to the EFI_FIRMWARE_IMAGE_DEP. - @param[in] MaxDepexSize Max size of the dependency. - @param[out] DepexSize Size of dependency. - - @retval TRUE The capsule is valid. - @retval FALSE The capsule is invalid. - -**/ -BOOLEAN -ValidateImageDepex ( - IN EFI_FIRMWARE_IMAGE_DEP *ImageDepex, - IN CONST UINTN MaxDepexSize, - OUT UINT32 *DepexSize - ); - -/** - Check dependency for firmware update. - - @param[in] ImageTypeId Image Type Id. - @param[in] Version New version. - @param[in] Dependencies The dependencies. - @param[in] DepexSize Size of the dependencies - @param[out] IsSatisfied Indicate the dependencies is satisfied = or not. - - @retval EFI_SUCCESS Dependency Evaluation is successful. - @retval Others Dependency Evaluation fails with unexpe= cted error. - -**/ -EFI_STATUS -EvaluateImageDependencies ( - IN CONST EFI_GUID ImageTypeId, - IN CONST UINT32 Version, - IN CONST EFI_FIRMWARE_IMAGE_DEP *Dependencies, - IN CONST UINT32 DepexSize, - OUT BOOLEAN *IsSatisfied - ); - -#endif diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c b/FmpDevicePkg/FmpDxe/FmpDxe.c index 5b523291e4..58841774fe 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.c +++ b/FmpDevicePkg/FmpDxe/FmpDxe.c @@ -10,11 +10,10 @@ =20 **/ =20 #include "FmpDxe.h" #include "VariableSupport.h" -#include "Dependency.h" =20 /// /// FILE_GUID from FmpDxe.inf. When FmpDxe.inf is used in a platform, the /// FILE_GUID must always be overridden in the section to provide /// the ESRT GUID value associated with the updatable firmware image. A @@ -79,11 +78,12 @@ const FIRMWARE_MANAGEMENT_PRIVATE_DATA mFirmwareManage= mentPrivateDataTemplate =3D NULL, // FmpDeviceContext NULL, // VersionVariableName NULL, // LsvVariableName NULL, // LastAttemptStatusVariabl= eName NULL, // LastAttemptVersionVariab= leName - NULL // FmpStateVariableName + NULL, // FmpStateVariableName + TRUE // DependenciesSatisfied }; =20 /// /// GUID that is used to create event used to lock the firmware storage de= vice. /// @@ -274,17 +274,11 @@ VOID PopulateDescriptor ( FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ) { EFI_STATUS Status; - VOID *Image; - UINTN ImageSize; - BOOLEAN IsDepexValid; - UINT32 DepexSize; - - Image =3D NULL; - ImageSize =3D 0; + UINT32 DependenciesSize; =20 if (Private->DescriptorPopulated) { return; } =20 @@ -385,50 +379,22 @@ PopulateDescriptor ( =20 Private->Descriptor.LastAttemptVersion =3D GetLastAttemptVersionFromVari= able (Private); Private->Descriptor.LastAttemptStatus =3D GetLastAttemptStatusFromVaria= ble (Private); =20 // - // Get the dependency from the FmpDeviceLib and populate it to the descr= iptor. + // Get the dependency from the FmpDependencyDeviceLib. // Private->Descriptor.Dependencies =3D NULL; =20 // // Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY // - if (Private->Descriptor.AttributesSupported & IMAGE_ATTRIBUTE_DEPENDENCY= ) { - // - // The parameter "Image" of FmpDeviceGetImage() is extended to contain= the dependency. - // Get the dependency from the Image. - // - ImageSize =3D Private->Descriptor.Size; - Image =3D AllocatePool (ImageSize); - if (Image !=3D NULL) { - Status =3D FmpDeviceGetImage (Image, &ImageSize); - if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { - FreePool (Image); - Image =3D AllocatePool (ImageSize); - if (Image !=3D NULL) { - Status =3D FmpDeviceGetImage (Image, &ImageSize); - } - } - } - if (!EFI_ERROR (Status) && Image !=3D NULL) { - IsDepexValid =3D ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP *) Imag= e, ImageSize, &DepexSize); - if (IsDepexValid) { - Private->Descriptor.Dependencies =3D AllocatePool (DepexSize); - if (Private->Descriptor.Dependencies !=3D NULL) { - CopyMem (Private->Descriptor.Dependencies->Dependencies, Image, = DepexSize); - } - } - } + if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) { + Private->Descriptor.Dependencies =3D GetFmpDependency (&DependenciesSi= ze); } =20 Private->DescriptorPopulated =3D TRUE; - - if (Image !=3D NULL) { - FreePool (Image); - } } =20 /** Returns information about the current firmware image(s) of the device. =20 @@ -586,21 +552,16 @@ GetTheImage ( ) { EFI_STATUS Status; FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private; UINTN Size; - UINT8 *ImageBuffer; - UINTN ImageBufferSize; - UINT32 DepexSize; =20 if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) { return EFI_UNSUPPORTED; } =20 - Status =3D EFI_SUCCESS; - ImageBuffer =3D NULL; - DepexSize =3D 0; + Status =3D EFI_SUCCESS; =20 // // Retrieve the private context structure // Private =3D FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This); @@ -626,49 +587,12 @@ GetTheImage ( // Status =3D FmpDeviceGetSize (&Size); if (EFI_ERROR (Status)) { Size =3D 0; } - - // - // The parameter "Image" of FmpDeviceGetImage() is extended to contain t= he dependency. - // Get the Fmp Payload from the Image. - // - ImageBufferSize =3D Size; - ImageBuffer =3D AllocatePool (ImageBufferSize); - if (ImageBuffer =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - AllocatePool fails.\n",= mImageIdName)); - Status =3D EFI_NOT_FOUND; - goto cleanup; - } - Status =3D FmpDeviceGetImage (ImageBuffer, &ImageBufferSize); - if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { - FreePool (ImageBuffer); - ImageBuffer =3D AllocatePool (ImageBufferSize); - if (ImageBuffer =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - AllocatePool fails.\n= ", mImageIdName)); - Status =3D EFI_NOT_FOUND; - goto cleanup; - } - Status =3D FmpDeviceGetImage (ImageBuffer, &ImageBufferSize); - } - if (EFI_ERROR (Status)) { - goto cleanup; - } - - // - // Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY - // - if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) { - // - // Validate the dependency to get its size. - // - ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP *) ImageBuffer, ImageBuffe= rSize, &DepexSize); - } - - if (*ImageSize < ImageBufferSize - DepexSize) { - *ImageSize =3D ImageBufferSize - DepexSize; + if (*ImageSize < Size) { + *ImageSize =3D Size; DEBUG ((DEBUG_VERBOSE, "FmpDxe(%s): GetImage() - ImageSize is to small= .\n", mImageIdName)); Status =3D EFI_BUFFER_TOO_SMALL; goto cleanup; } =20 @@ -676,57 +600,50 @@ GetTheImage ( DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - Image Pointer Parameter= is NULL.\n", mImageIdName)); Status =3D EFI_INVALID_PARAMETER; goto cleanup; } =20 - // - // Image is after the dependency expression. - // - *ImageSize =3D ImageBufferSize - DepexSize; - CopyMem (Image, ImageBuffer + DepexSize, *ImageSize); - Status =3D EFI_SUCCESS; - + Status =3D FmpDeviceGetImage (Image, ImageSize); cleanup: - if (ImageBuffer !=3D NULL) { - FreePool (ImageBuffer); - } =20 return Status; } =20 /** Helper function to safely retrieve the FMP header from within an EFI_FIRMWARE_IMAGE_AUTHENTICATION structure. =20 - @param[in] Image Pointer to the image. - @param[in] ImageSize Size of the image. + @param[in] Image Pointer to the image. + @param[in] ImageSize Size of the image. + @param[in] AdditionalHeaderSize Size of any headers that cannot be ca= lculated by this function. @param[out] PayloadSize =20 @retval !NULL Valid pointer to the header. @retval NULL Structure is bad and pointer cannot be found. =20 **/ VOID * GetFmpHeader ( IN CONST EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image, IN CONST UINTN ImageSize, + IN CONST UINTN AdditionalHeaderSize, OUT UINTN *PayloadSize ) { // // Check to make sure that operation can be safely performed. // - if (((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr= .dwLength) < (UINTN)Image || \ - ((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr= .dwLength) >=3D (UINTN)Image + ImageSize) { + if (((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr= .dwLength) + AdditionalHeaderSize < (UINTN)Image || \ + ((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr= .dwLength) + AdditionalHeaderSize >=3D (UINTN)Image + ImageSize) { // // Pointer overflow. Invalid image. // return NULL; } =20 - *PayloadSize =3D ImageSize - (sizeof (Image->MonotonicCount) + Image->Au= thInfo.Hdr.dwLength); - return (VOID *)((UINT8 *)Image + sizeof (Image->MonotonicCount) + Image-= >AuthInfo.Hdr.dwLength); + *PayloadSize =3D ImageSize - (sizeof (Image->MonotonicCount) + Image->Au= thInfo.Hdr.dwLength + AdditionalHeaderSize); + return (VOID *)((UINT8 *)Image + sizeof (Image->MonotonicCount) + Image-= >AuthInfo.Hdr.dwLength + AdditionalHeaderSize); } =20 /** Helper function to safely calculate the size of all headers within an EFI_FIRMWARE_IMAGE_AUTHENTICATION structure. @@ -809,12 +726,10 @@ CheckTheImage ( UINTN PublicKeyDataLength; UINT8 *PublicKeyDataXdr; UINT8 *PublicKeyDataXdrEnd; EFI_FIRMWARE_IMAGE_DEP *Dependencies; UINT32 DependenciesSize; - BOOLEAN IsDepexValid; - BOOLEAN IsDepexSatisfied; =20 Status =3D EFI_SUCCESS; RawSize =3D 0; FmpPayloadHeader =3D NULL; FmpPayloadSize =3D 0; @@ -848,10 +763,15 @@ CheckTheImage ( // //Set to valid and then if any tests fail it will update this flag. // *ImageUpdatable =3D IMAGE_UPDATABLE_VALID; =20 + // + // Set to satisfied and then if dependency evaluates to false it will up= date this flag. + // + Private->DependenciesSatisfied =3D TRUE; + if (Image =3D=3D NULL) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckImage() - Image Pointer Paramet= er is NULL.\n", mImageIdName)); // // not sure if this is needed // @@ -933,49 +853,30 @@ CheckTheImage ( *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID_TYPE; Status =3D EFI_SUCCESS; goto cleanup; } =20 + // + // Get the dependency from Image. + // + Dependencies =3D GetImageDependency ((EFI_FIRMWARE_IMAGE_AUTHENTICATION = *)Image, ImageSize, &DependenciesSize); =20 // // Check the FmpPayloadHeader // - FmpPayloadHeader =3D GetFmpHeader ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *= )Image, ImageSize, &FmpPayloadSize ); + FmpPayloadHeader =3D GetFmpHeader ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *= )Image, ImageSize, DependenciesSize, &FmpPayloadSize ); if (FmpPayloadHeader =3D=3D NULL) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpHeader faile= d.\n", mImageIdName)); Status =3D EFI_ABORTED; goto cleanup; } Status =3D GetFmpPayloadHeaderVersion (FmpPayloadHeader, FmpPayloadSize,= &Version); if (EFI_ERROR (Status)) { - // - // Check if there is dependency expression - // - IsDepexValid =3D ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP*) FmpPayl= oadHeader, FmpPayloadSize, &DependenciesSize); - if (IsDepexValid && (DependenciesSize < FmpPayloadSize)) { - // - // Fmp payload is after dependency expression - // - Dependencies =3D (EFI_FIRMWARE_IMAGE_DEP*) FmpPayloadHeader; - FmpPayloadHeader =3D (UINT8 *) Dependencies + DependenciesSize; - FmpPayloadSize =3D FmpPayloadSize - DependenciesSize; - Status =3D GetFmpPayloadHeaderVersion (FmpPayloadHeader, FmpPayloadS= ize, &Version); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpPayloadH= eaderVersion failed %r.\n", mImageIdName, Status)); - *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; - Status =3D EFI_SUCCESS; - goto cleanup; - } - } else { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency is in= valid.\n", mImageIdName)); - mDependenciesCheckStatus =3D DEPENDENCIES_INVALID; - *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; - Status =3D EFI_SUCCESS; - goto cleanup; - } - } else { - DEBUG ((DEBUG_WARN, "FmpDxe(%s): CheckTheImage() - No dependency assoc= iated in image.\n", mImageIdName)); + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpPayloadHeade= rVersion failed %r.\n", mImageIdName, Status)); + *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; + Status =3D EFI_SUCCESS; + goto cleanup; } =20 // // Check the lowest supported version // @@ -991,18 +892,13 @@ CheckTheImage ( } =20 // // Evaluate dependency expression // - Status =3D EvaluateImageDependencies (Private->Descriptor.ImageTypeId, V= ersion, Dependencies, DependenciesSize, &IsDepexSatisfied); - if (!IsDepexSatisfied || EFI_ERROR (Status)) { - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency check= failed %r.\n", mImageIdName, Status)); - } else { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency is no= t satisfied.\n", mImageIdName)); - } - mDependenciesCheckStatus =3D DEPENDENCIES_UNSATISFIED; + Private->DependenciesSatisfied =3D CheckFmpDependency (Private->Descript= or.ImageTypeId, Version, Dependencies, DependenciesSize); + if (!Private->DependenciesSatisfied) { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency check f= ailed.\n", mImageIdName)); *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; Status =3D EFI_SUCCESS; goto cleanup; } =20 @@ -1111,13 +1007,10 @@ SetTheImage ( UINT32 LastAttemptStatus; UINT32 Version; UINT32 LowestSupportedVersion; EFI_FIRMWARE_IMAGE_DEP *Dependencies; UINT32 DependenciesSize; - BOOLEAN IsDepexValid; - UINT8 *ImageBuffer; - UINTN ImageBufferSize; =20 Status =3D EFI_SUCCESS; Updateable =3D 0; BooleanValue =3D FALSE; FmpHeaderSize =3D 0; @@ -1126,12 +1019,10 @@ SetTheImage ( AllHeaderSize =3D 0; IncomingFwVersion =3D 0; LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; Dependencies =3D NULL; DependenciesSize =3D 0; - ImageBuffer =3D NULL; - ImageBufferSize =3D 0; =20 if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) { return EFI_UNSUPPORTED; } =20 @@ -1159,15 +1050,10 @@ SetTheImage ( DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Device is already lo= cked. Can't update.\n", mImageIdName)); Status =3D EFI_UNSUPPORTED; goto cleanup; } =20 - // - // Set check status to satisfied before CheckTheImage() - // - mDependenciesCheckStatus =3D DEPENDENCIES_SATISFIED; - // // Call check image to verify the image // Status =3D CheckTheImage (This, ImageIndex, Image, ImageSize, &Updateabl= e); if (EFI_ERROR (Status)) { @@ -1176,36 +1062,26 @@ SetTheImage ( LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR; } goto cleanup; } =20 + // + // Get the dependency from Image. + // + Dependencies =3D GetImageDependency ((EFI_FIRMWARE_IMAGE_AUTHENTICATION = *)Image, ImageSize, &DependenciesSize); + // // No functional error in CheckTheImage. Attempt to get the Version to // support better error reporting. // - FmpHeader =3D GetFmpHeader ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image,= ImageSize, &FmpPayloadSize ); + FmpHeader =3D GetFmpHeader ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image,= ImageSize, DependenciesSize, &FmpPayloadSize ); if (FmpHeader =3D=3D NULL) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetFmpHeader failed.= \n", mImageIdName)); Status =3D EFI_ABORTED; goto cleanup; } Status =3D GetFmpPayloadHeaderVersion (FmpHeader, FmpPayloadSize, &Incom= ingFwVersion); - if (EFI_ERROR (Status)) { - // - // Check if there is dependency expression - // - IsDepexValid =3D ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP*) FmpHead= er, FmpPayloadSize, &DependenciesSize); - if (IsDepexValid && (DependenciesSize < FmpPayloadSize)) { - // - // Fmp payload is after dependency expression - // - Dependencies =3D (EFI_FIRMWARE_IMAGE_DEP*) FmpHeader; - FmpHeader =3D (UINT8 *) FmpHeader + DependenciesSize; - FmpPayloadSize =3D FmpPayloadSize - DependenciesSize; - Status =3D GetFmpPayloadHeaderVersion (FmpHeader, FmpPayloadSize, &I= ncomingFwVersion); - } - } if (!EFI_ERROR (Status)) { // // Set to actual value // SetLastAttemptVersionInVariable (Private, IncomingFwVersion); @@ -1216,14 +1092,12 @@ SetTheImage ( DEBUG ( (DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Check The Image returned that the Image= was not valid for update. Updatable value =3D 0x%X.\n", mImageIdName, Updateable) ); - if (mDependenciesCheckStatus =3D=3D DEPENDENCIES_UNSATISFIED) { + if (Private->DependenciesSatisfied =3D=3D FALSE) { LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDEN= CIES; - } else if (mDependenciesCheckStatus =3D=3D DEPENDENCIES_INVALID) { - LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; } Status =3D EFI_ABORTED; goto cleanup; } =20 @@ -1321,59 +1195,41 @@ SetTheImage ( DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetAllHeaderSize fai= led.\n", mImageIdName)); Status =3D EFI_ABORTED; goto cleanup; } =20 - // - // Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY - // - if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) { - // - // To support saving dependency, extend param "Image" of FmpDeviceSetI= mage() to - // contain the dependency inside. FmpDeviceSetImage() is responsible f= or saving - // the dependency which can be used for future dependency check. - // - ImageBufferSize =3D DependenciesSize + ImageSize - AllHeaderSize; - ImageBuffer =3D AllocatePool (ImageBufferSize); - if (ImageBuffer =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - AllocatePool faile= d.\n", mImageIdName)); - Status =3D EFI_ABORTED; - goto cleanup; - } - CopyMem (ImageBuffer, Dependencies->Dependencies, DependenciesSize); - CopyMem (ImageBuffer + DependenciesSize, (UINT8 *)Image + AllHeaderSiz= e, ImageBufferSize - DependenciesSize); - } else { - ImageBufferSize =3D ImageSize - AllHeaderSize; - ImageBuffer =3D AllocateCopyPool(ImageBufferSize, (UINT8 *)Image + All= HeaderSize); - if (ImageBuffer =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - AllocatePool faile= d.\n", mImageIdName)); - Status =3D EFI_ABORTED; - goto cleanup; - } - } - // // Indicate that control is handed off to FmpDeviceLib // Progress (5); =20 // //Copy the requested image to the firmware using the FmpDeviceLib // Status =3D FmpDeviceSetImage ( - ImageBuffer, - ImageBufferSize, + (((UINT8 *)Image) + AllHeaderSize), + ImageSize - AllHeaderSize, VendorCode, FmpDxeProgress, IncomingFwVersion, AbortReason ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() SetImage from FmpDevic= eLib failed. Status =3D %r.\n", mImageIdName, Status)); goto cleanup; } =20 + // + // Store the dependency + // + if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) { + Status =3D SaveFmpDependency (Dependencies, DependenciesSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() SaveFmpDependency fr= om FmpDependencyCheckLib failed. (%r)\n", mImageIdName, Status)); + } + Status =3D EFI_SUCCESS; + } =20 // // Finished the update without error // Indicate that control has been returned from FmpDeviceLib // @@ -1396,14 +1252,10 @@ SetTheImage ( SetLowestSupportedVersionInVariable (Private, LowestSupportedVersion); =20 LastAttemptStatus =3D LAST_ATTEMPT_STATUS_SUCCESS; =20 cleanup: - if (ImageBuffer !=3D NULL) { - FreePool (ImageBuffer); - } - mProgressFunc =3D NULL; SetLastAttemptStatusInVariable (Private, LastAttemptStatus); =20 if (Progress !=3D NULL) { // diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.h b/FmpDevicePkg/FmpDxe/FmpDxe.h index 150f18b656..30754dea49 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.h +++ b/FmpDevicePkg/FmpDxe/FmpDxe.h @@ -26,10 +26,13 @@ #include #include #include #include #include +#include +#include +#include #include #include #include #include #include @@ -64,10 +67,11 @@ typedef struct { CHAR16 *VersionVariableName; CHAR16 *LsvVariableName; CHAR16 *LastAttemptStatusVariableN= ame; CHAR16 *LastAttemptVersionVariable= Name; CHAR16 *FmpStateVariableName; + BOOLEAN DependenciesSatisfied; } FIRMWARE_MANAGEMENT_PRIVATE_DATA; =20 /// /// /// diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.inf b/FmpDevicePkg/FmpDxe/FmpDxe.inf index 97b6518fa1..eeb904a091 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.inf +++ b/FmpDevicePkg/FmpDxe/FmpDxe.inf @@ -26,12 +26,10 @@ # =20 [Sources] FmpDxe.c FmpDxe.h - Dependency.c - Dependency.h DetectTestKey.c VariableSupport.h VariableSupport.c =20 [Packages] @@ -52,10 +50,13 @@ BaseCryptLib FmpAuthenticationLib FmpDeviceLib FmpPayloadHeaderLib CapsuleUpdatePolicyLib + FmpDependencyLib + FmpDependencyCheckLib + FmpDependencyDeviceLib =20 [Guids] gEfiEndOfDxeEventGroupGuid =20 [Protocols] diff --git a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf b/FmpDevicePkg/FmpDxe/FmpDxe= Lib.inf index de005b6892..9a93b5e6ac 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf +++ b/FmpDevicePkg/FmpDxe/FmpDxeLib.inf @@ -27,12 +27,10 @@ # =20 [Sources] FmpDxe.c FmpDxe.h - Dependency.c - Dependency.h DetectTestKey.c VariableSupport.h VariableSupport.c =20 [Packages] @@ -52,10 +50,13 @@ BaseCryptLib FmpAuthenticationLib FmpDeviceLib FmpPayloadHeaderLib CapsuleUpdatePolicyLib + FmpDependencyLib + FmpDependencyCheckLib + FmpDependencyDeviceLib =20 [Guids] gEfiEndOfDxeEventGroupGuid =20 [Protocols] --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#59607): https://edk2.groups.io/g/devel/message/59607 Mute This Topic: https://groups.io/mt/74215668/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-