This is an in/out parameter and it is 1-based,\r
to deal with recursions.\r
@param SectionDefinitionGuid Guid of section definition\r
+ @param Depth Nesting depth of encapsulation sections.\r
+ Callers different from FindChildNode() are\r
+ responsible for passing in a zero Depth.\r
@param FoundChild Output indicating the child node that is found.\r
@param FoundStream Output indicating which section stream the child\r
was found in. If this stream was generated as a\r
@retval EFI_NOT_FOUND Requested child node does not exist.\r
@retval EFI_PROTOCOL_ERROR a required GUIDED section extraction protocol\r
does not exist\r
+ @retval EFI_ABORTED Recursion aborted because Depth has been\r
+ greater than or equal to\r
+ PcdFwVolDxeMaxEncapsulationDepth.\r
\r
**/\r
EFI_STATUS\r
IN EFI_SECTION_TYPE SearchType,\r
IN OUT UINTN *SectionInstance,\r
IN EFI_GUID *SectionDefinitionGuid,\r
+ IN UINT32 Depth,\r
OUT CORE_SECTION_CHILD_NODE **FoundChild,\r
OUT CORE_SECTION_STREAM_NODE **FoundStream,\r
OUT UINT32 *AuthenticationStatus\r
\r
ASSERT (*SectionInstance > 0);\r
\r
+ if (Depth >= PcdGet32 (PcdFwVolDxeMaxEncapsulationDepth)) {\r
+ return EFI_ABORTED;\r
+ }\r
+\r
CurrentChildNode = NULL;\r
ErrorStatus = EFI_NOT_FOUND;\r
\r
SearchType,\r
SectionInstance,\r
SectionDefinitionGuid,\r
+ Depth + 1,\r
&RecursedChildNode,\r
&RecursedFoundStream,\r
AuthenticationStatus\r
*FoundStream = RecursedFoundStream;\r
return EFI_SUCCESS;\r
} else {\r
+ if (Status == EFI_ABORTED) {\r
+ //\r
+ // If the recursive call was aborted due to nesting depth, stop\r
+ // looking for the requested child node. The skipped subtree could\r
+ // throw off the instance counting.\r
+ //\r
+ return Status;\r
+ }\r
//\r
- // If the status is not EFI_SUCCESS, just save the error code and\r
- // continue to find the request child node in the rest stream.\r
+ // Save the error code and continue to find the requested child node in\r
+ // the rest of the stream.\r
//\r
ErrorStatus = Status;\r
}\r
*SectionType,\r
&Instance,\r
SectionDefinitionGuid,\r
+ 0, // encapsulation depth\r
&ChildNode,\r
&ChildStreamNode,\r
&ExtractedAuthenticationStatus\r
);\r
if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_ABORTED) {\r
+ DEBUG ((DEBUG_ERROR, "%a: recursion aborted due to nesting depth\n",\r
+ __FUNCTION__));\r
+ //\r
+ // Map "aborted" to "not found".\r
+ //\r
+ Status = EFI_NOT_FOUND;\r
+ }\r
goto GetSection_Done;\r
}\r
\r
# @Prompt Enable Capsule On Disk support.\r
gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleOnDiskSupport|FALSE|BOOLEAN|0x0000002d\r
\r
+ ## Maximum permitted encapsulation levels of sections in a firmware volume,\r
+ # in the DXE phase. Minimum value is 1. Sections nested more deeply are\r
+ # rejected.\r
+ # @Prompt Maximum permitted FwVol section nesting depth (exclusive).\r
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth|0x10|UINT32|0x00000030\r
+\r
[PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]\r
## This PCD defines the Console output row. The default value is 25 according to UEFI spec.\r
# This PCD could be set to 0 then console output would be at max column and max row.\r
"Note:<BR>"\r
"If Both Capsule In Ram and Capsule On Disk are provisioned at the same time, the Capsule On Disk will be bypassed."\r
\r
+#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdFwVolDxeMaxEncapsulationDepth_PROMPT #language en-US "Maximum permitted FwVol section nesting depth (exclusive)."\r
+\r
+#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdFwVolDxeMaxEncapsulationDepth_HELP #language en-US "Maximum permitted encapsulation levels of sections in a firmware volume,<BR>"\r
+ "in the DXE phase. Minimum value is 1. Sections nested more deeply are<BR>"\r
+ "rejected."\r
+\r
#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdCapsuleInRamSupport_PROMPT #language en-US "Enable Capsule In Ram support"\r
\r
#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdCapsuleInRamSupport_HELP #language en-US "Capsule In Ram is to use memory to deliver the capsules that will be processed after system reset.<BR><BR>"\r