]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
MdeModulePkg/UdfDxe: Add boundary check the read of FE/EFE
[mirror_edk2.git] / MdeModulePkg / Universal / Disk / UdfDxe / FileSystemOperations.c
index b3ac673cac4952518d65cbe6635566abc2a605f4..c7d9ad498c48c390785707605a28cad9c52631bb 100644 (file)
@@ -516,15 +516,27 @@ DuplicateFe (
 \r
   NOTE: The FE/EFE can be thought it was an inode.\r
 \r
+  @attention This is boundary function that may receive untrusted input.\r
+  @attention The input is from FileSystem.\r
+\r
+  The (Extended) File Entry is external input, so this routine will do basic\r
+  validation for (Extended) File Entry and report status.\r
+\r
   @param[in]  FileEntryData       (Extended) File Entry pointer.\r
+  @param[in]  FileEntrySize       Size of the (Extended) File Entry specified\r
+                                  by FileEntryData.\r
   @param[out] Data                Buffer contains the raw data of a given\r
                                   (Extended) File Entry.\r
   @param[out] Length              Length of the data in Buffer.\r
 \r
+  @retval EFI_SUCCESS             Raw data and size of the FE/EFE was read.\r
+  @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.\r
+\r
 **/\r
-VOID\r
+EFI_STATUS\r
 GetFileEntryData (\r
   IN   VOID    *FileEntryData,\r
+  IN   UINTN   FileEntrySize,\r
   OUT  VOID    **Data,\r
   OUT  UINT64  *Length\r
   )\r
@@ -548,20 +560,40 @@ GetFileEntryData (
     *Data    = (VOID *)((UINT8 *)FileEntry->Data +\r
                         FileEntry->LengthOfExtendedAttributes);\r
   }\r
+\r
+  if ((*Length > FileEntrySize) ||\r
+      ((UINTN)FileEntryData > (UINTN)(*Data)) ||\r
+      ((UINTN)(*Data) - (UINTN)FileEntryData > FileEntrySize - *Length)) {\r
+    return EFI_VOLUME_CORRUPTED;\r
+  }\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
   Get Allocation Descriptors' data information from a given FE/EFE.\r
 \r
+  @attention This is boundary function that may receive untrusted input.\r
+  @attention The input is from FileSystem.\r
+\r
+  The (Extended) File Entry is external input, so this routine will do basic\r
+  validation for (Extended) File Entry and report status.\r
+\r
   @param[in]  FileEntryData       (Extended) File Entry pointer.\r
+  @param[in]  FileEntrySize       Size of the (Extended) File Entry specified\r
+                                  by FileEntryData.\r
   @param[out] AdsData             Buffer contains the Allocation Descriptors'\r
                                   data from a given FE/EFE.\r
   @param[out] Length              Length of the data in AdsData.\r
 \r
+  @retval EFI_SUCCESS             The data and size of Allocation Descriptors\r
+                                  were read from the FE/EFE.\r
+  @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.\r
+\r
 **/\r
-VOID\r
+EFI_STATUS\r
 GetAdsInformation (\r
   IN   VOID    *FileEntryData,\r
+  IN   UINTN   FileEntrySize,\r
   OUT  VOID    **AdsData,\r
   OUT  UINT64  *Length\r
   )\r
@@ -585,6 +617,13 @@ GetAdsInformation (
     *AdsData = (VOID *)((UINT8 *)FileEntry->Data +\r
                         FileEntry->LengthOfExtendedAttributes);\r
   }\r
+\r
+  if ((*Length > FileEntrySize) ||\r
+      ((UINTN)FileEntryData > (UINTN)(*AdsData)) ||\r
+      ((UINTN)(*AdsData) - (UINTN)FileEntryData > FileEntrySize - *Length)) {\r
+    return EFI_VOLUME_CORRUPTED;\r
+  }\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -1099,7 +1138,10 @@ ReadFile (
     //\r
     // There are no extents for this FE/EFE. All data is inline.\r
     //\r
-    GetFileEntryData (FileEntryData, &Data, &Length);\r
+    Status = GetFileEntryData (FileEntryData, Volume->FileEntrySize, &Data, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
 \r
     if (ReadFileInfo->Flags == ReadFileGetFileSize) {\r
       ReadFileInfo->ReadLength = Length;\r
@@ -1143,7 +1185,11 @@ ReadFile (
     // This FE/EFE contains a run of Allocation Descriptors. Get data + size\r
     // for start reading them out.\r
     //\r
-    GetAdsInformation (FileEntryData, &Data, &Length);\r
+    Status = GetAdsInformation (FileEntryData, Volume->FileEntrySize, &Data, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
     AdOffset = 0;\r
 \r
     for (;;) {\r