]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c
MdeModulePkg/Core/Dxe: limit FwVol encapsulation section recursion
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / SectionExtraction / CoreSectionExtraction.c
index d7f7ef427422cb7044fc775dac4eec5bd7341e1a..908617d1ca5c37e0caf7fb59eb05534f32191fed 100644 (file)
@@ -955,6 +955,9 @@ CreateChildNode (
                                  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
@@ -968,6 +971,9 @@ CreateChildNode (
   @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
@@ -976,6 +982,7 @@ FindChildNode (
   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
@@ -990,6 +997,10 @@ FindChildNode (
 \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
@@ -1053,6 +1064,7 @@ FindChildNode (
                 SearchType,\r
                 SectionInstance,\r
                 SectionDefinitionGuid,\r
+                Depth + 1,\r
                 &RecursedChildNode,\r
                 &RecursedFoundStream,\r
                 AuthenticationStatus\r
@@ -1067,9 +1079,17 @@ FindChildNode (
         *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
@@ -1272,11 +1292,20 @@ GetSection (
                *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