Ext4Pkg: Various improvements based on Sydr fuzzing results.

Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
This commit is contained in:
Mikhail Krichanov 2024-07-22 12:30:43 +03:00
parent 0f4eb39d08
commit 4928d441c2

View File

@ -39,8 +39,11 @@ Ext4CalculateExtentChecksum (
@param[in] File Pointer to the open file. @param[in] File Pointer to the open file.
@param[in] Extents Pointer to an array of extents. @param[in] Extents Pointer to an array of extents.
@param[in] NumberExtents Length of the array. @param[in] NumberExtents Length of the array.
@return Result of the caching
**/ **/
VOID STATIC
EFI_STATUS
Ext4CacheExtents ( Ext4CacheExtents (
IN EXT4_FILE *File, IN EXT4_FILE *File,
IN CONST EXT4_EXTENT *Extents, IN CONST EXT4_EXTENT *Extents,
@ -254,7 +257,7 @@ Ext4GetExtent (
EXT4_EXTENT_HEADER *ExtHeader; EXT4_EXTENT_HEADER *ExtHeader;
EXT4_EXTENT_INDEX *Index; EXT4_EXTENT_INDEX *Index;
EFI_STATUS Status; EFI_STATUS Status;
UINT32 MaxExtentsPerNode; UINT16 MaxExtentsPerNode;
EXT4_BLOCK_NR BlockNumber; EXT4_BLOCK_NR BlockNumber;
Inode = File->Inode; Inode = File->Inode;
@ -283,7 +286,13 @@ Ext4GetExtent (
Status = Ext4GetBlocks (Partition, File, (UINT32)LogicalBlock, Extent); Status = Ext4GetBlocks (Partition, File, (UINT32)LogicalBlock, Extent);
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
Ext4CacheExtents (File, Extent, 1); Status = Ext4CacheExtents (File, Extent, 1);
if (EFI_ERROR (Status) && (Status != EFI_OUT_OF_RESOURCES)) {
return Status;
}
Status = EFI_SUCCESS;
} }
return Status; return Status;
@ -302,7 +311,7 @@ Ext4GetExtent (
// A single node fits into a single block, so we can only have (BlockSize / sizeof(EXT4_EXTENT)) - 1 // A single node fits into a single block, so we can only have (BlockSize / sizeof(EXT4_EXTENT)) - 1
// extents in a single node. Note the -1, because both leaf and internal node headers are 12 bytes, // extents in a single node. Note the -1, because both leaf and internal node headers are 12 bytes,
// and so are individual entries. // and so are individual entries.
MaxExtentsPerNode = (Partition->BlockSize / sizeof (EXT4_EXTENT)) - 1; MaxExtentsPerNode = (UINT16)((Partition->BlockSize / sizeof (EXT4_EXTENT)) - 1);
while (ExtHeader->eh_depth != 0) { while (ExtHeader->eh_depth != 0) {
CurrentDepth--; CurrentDepth--;
@ -363,7 +372,15 @@ Ext4GetExtent (
* by linux (and possibly other systems) is quite fancy and usually it results in a small number of extents. * by linux (and possibly other systems) is quite fancy and usually it results in a small number of extents.
* Therefore, we shouldn't have any memory issues. * Therefore, we shouldn't have any memory issues.
**/ **/
Ext4CacheExtents (File, (EXT4_EXTENT *)(ExtHeader + 1), ExtHeader->eh_entries); Status = Ext4CacheExtents (File, (EXT4_EXTENT *)(ExtHeader + 1), ExtHeader->eh_entries);
if (EFI_ERROR (Status) && (Status != EFI_OUT_OF_RESOURCES)) {
if (Buffer != NULL) {
FreePool (Buffer);
}
return Status;
}
Ext = Ext4BinsearchExtentExt (ExtHeader, LogicalBlock); Ext = Ext4BinsearchExtentExt (ExtHeader, LogicalBlock);
@ -519,8 +536,11 @@ Ext4FreeExtentsMap (
@param[in] File Pointer to the open file. @param[in] File Pointer to the open file.
@param[in] Extents Pointer to an array of extents. @param[in] Extents Pointer to an array of extents.
@param[in] NumberExtents Length of the array. @param[in] NumberExtents Length of the array.
@return Result of the caching
**/ **/
VOID STATIC
EFI_STATUS
Ext4CacheExtents ( Ext4CacheExtents (
IN EXT4_FILE *File, IN EXT4_FILE *File,
IN CONST EXT4_EXTENT *Extents, IN CONST EXT4_EXTENT *Extents,
@ -536,10 +556,15 @@ Ext4CacheExtents (
*/ */
for (Idx = 0; Idx < NumberExtents; Idx++, Extents++) { for (Idx = 0; Idx < NumberExtents; Idx++, Extents++) {
if (Extents->ee_len == 0) {
// 0-sized extent, must be corruption
return EFI_VOLUME_CORRUPTED;
}
Extent = AllocatePool (sizeof (EXT4_EXTENT)); Extent = AllocatePool (sizeof (EXT4_EXTENT));
if (Extent == NULL) { if (Extent == NULL) {
return; return EFI_OUT_OF_RESOURCES;
} }
CopyMem (Extent, Extents, sizeof (EXT4_EXTENT)); CopyMem (Extent, Extents, sizeof (EXT4_EXTENT));
@ -553,9 +578,11 @@ Ext4CacheExtents (
continue; continue;
} }
return; return EFI_SUCCESS;
} }
} }
return EFI_SUCCESS;
} }
/** /**