REF:https://bugzilla.tianocore.org/show_bug.cgi?id=828
Within ReadFile():
Add checks to ensure that when getting the raw data or the Allocation
Descriptors' data from a FE/EFE, it will not consume data beyond the
size of a FE/EFE.
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Hao Wu <hao.a.wu@intel.com>
Reviewed-by: Paulo Alcantara <palcantara@suse.de>
Acked-by: Star Zeng <star.zeng@intel.com>
\r
NOTE: The FE/EFE can be thought it was an inode.\r
\r
\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] 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
@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
GetFileEntryData (\r
IN VOID *FileEntryData,\r
GetFileEntryData (\r
IN VOID *FileEntryData,\r
+ IN UINTN FileEntrySize,\r
OUT VOID **Data,\r
OUT UINT64 *Length\r
)\r
OUT VOID **Data,\r
OUT UINT64 *Length\r
)\r
*Data = (VOID *)((UINT8 *)FileEntry->Data +\r
FileEntry->LengthOfExtendedAttributes);\r
}\r
*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
}\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] 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
@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
GetAdsInformation (\r
IN VOID *FileEntryData,\r
GetAdsInformation (\r
IN VOID *FileEntryData,\r
+ IN UINTN FileEntrySize,\r
OUT VOID **AdsData,\r
OUT UINT64 *Length\r
)\r
OUT VOID **AdsData,\r
OUT UINT64 *Length\r
)\r
*AdsData = (VOID *)((UINT8 *)FileEntry->Data +\r
FileEntry->LengthOfExtendedAttributes);\r
}\r
*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
// There are no extents for this FE/EFE. All data is inline.\r
//\r
//\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
\r
if (ReadFileInfo->Flags == ReadFileGetFileSize) {\r
ReadFileInfo->ReadLength = Length;\r
// This FE/EFE contains a run of Allocation Descriptors. Get data + size\r
// for start reading them out.\r
//\r
// 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
AdOffset = 0;\r
\r
for (;;) {\r