Thank you! Merged the patchset as 82f4b39 and 9247980, respectively. On Tue, May 9, 2023 at 5:07 PM Marvin Häuser <mhaeu...@posteo.de> wrote: > > Reviewed-by: Marvin Häuser <mhaeu...@posteo.de> > > > On 9. May 2023, at 17:49, Pedro Falcato <pedro.falc...@gmail.com> wrote: > > > > Improve the extent tree node validation by validating the number of > > entries the node advertises against the theoretical max (derived from > > the size of on-disk structs and the block size (or i_data, if inline > > extents). > > > > Previously, we did not validate the number of entries. This could be > > exploited for out-of-bounds reads and crashes. > > > > Cc: Marvin Häuser <mhaeu...@posteo.de> > > Fixes: d9ceedca6c8f ("Ext4Pkg: Add Ext4Dxe driver.") > > Reported-by: Savva Mitrofanov <savva...@gmail.com> > > Signed-off-by: Pedro Falcato <pedro.falc...@gmail.com> > > --- > > Features/Ext4Pkg/Ext4Dxe/Extents.c | 32 ++++++++++++++++++++++++++---- > > 1 file changed, 28 insertions(+), 4 deletions(-) > > > > diff --git a/Features/Ext4Pkg/Ext4Dxe/Extents.c > > b/Features/Ext4Pkg/Ext4Dxe/Extents.c > > index 9e4364e50d99..2b82417c9e10 100644 > > --- a/Features/Ext4Pkg/Ext4Dxe/Extents.c > > +++ b/Features/Ext4Pkg/Ext4Dxe/Extents.c > > @@ -1,7 +1,7 @@ > > /** @file > > Extent related routines > > > > - Copyright (c) 2021 - 2022 Pedro Falcato All rights reserved. > > + Copyright (c) 2021 - 2023 Pedro Falcato All rights reserved. > > SPDX-License-Identifier: BSD-2-Clause-Patent > > **/ > > > > @@ -80,13 +80,15 @@ Ext4GetInoExtentHeader ( > > /** > > Checks if an extent header is valid. > > @param[in] Header Pointer to the EXT4_EXTENT_HEADER > > structure. > > + @param[in] MaxEntries Maximum number of entries possible for > > this tree node. > > > > @return TRUE if valid, FALSE if not. > > **/ > > STATIC > > BOOLEAN > > Ext4ExtentHeaderValid ( > > - IN CONST EXT4_EXTENT_HEADER *Header > > + IN CONST EXT4_EXTENT_HEADER *Header, > > + IN UINT16 MaxEntries > > ) > > { > > if (Header->eh_depth > EXT4_EXTENT_TREE_MAX_DEPTH) { > > @@ -99,6 +101,18 @@ Ext4ExtentHeaderValid ( > > return FALSE; > > } > > > > + // Note: We do not need to check eh_entries here, as the next branch > > makes sure max >= entries > > + if (Header->eh_max > MaxEntries) { > > + DEBUG (( > > + DEBUG_ERROR, > > + "[ext4] Invalid extent header max entries (%u eh_max, " > > + "theoretical max is %u) (larger than permitted)\n", > > + Header->eh_max, > > + MaxEntries > > + )); > > + return FALSE; > > + } > > + > > if (Header->eh_max < Header->eh_entries) { > > DEBUG (( > > DEBUG_ERROR, > > @@ -212,6 +226,9 @@ Ext4ExtentIdxLeafBlock ( > > return LShiftU64 (Index->ei_leaf_hi, 32) | Index->ei_leaf_lo; > > } > > > > +// Results of sizeof(i_data) / sizeof(extent) - 1 = 4 > > +#define EXT4_NR_INLINE_EXTENTS 4 > > + > > /** > > Retrieves an extent from an EXT4 inode. > > @param[in] Partition Pointer to the opened EXT4 partition. > > @@ -237,6 +254,7 @@ Ext4GetExtent ( > > EXT4_EXTENT_HEADER *ExtHeader; > > EXT4_EXTENT_INDEX *Index; > > EFI_STATUS Status; > > + UINT32 MaxExtentsPerNode; > > EXT4_BLOCK_NR BlockNumber; > > > > Inode = File->Inode; > > @@ -275,12 +293,17 @@ Ext4GetExtent ( > > > > ExtHeader = Ext4GetInoExtentHeader (Inode); > > > > - if (!Ext4ExtentHeaderValid (ExtHeader)) { > > + if (!Ext4ExtentHeaderValid (ExtHeader, EXT4_NR_INLINE_EXTENTS)) { > > return EFI_VOLUME_CORRUPTED; > > } > > > > CurrentDepth = ExtHeader->eh_depth; > > > > + // 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, > > + // and so are individual entries. > > + MaxExtentsPerNode = (Partition->BlockSize / sizeof (EXT4_EXTENT)) - 1; > > + > > while (ExtHeader->eh_depth != 0) { > > CurrentDepth--; > > // While depth != 0, we're traversing the tree itself and not any leaves > > @@ -309,6 +332,7 @@ Ext4GetExtent ( > > } > > > > // Read the leaf block onto the previously-allocated buffer. > > + > > Status = Ext4ReadBlocks (Partition, Buffer, 1, BlockNumber); > > if (EFI_ERROR (Status)) { > > FreePool (Buffer); > > @@ -317,7 +341,7 @@ Ext4GetExtent ( > > > > ExtHeader = Buffer; > > > > - if (!Ext4ExtentHeaderValid (ExtHeader)) { > > + if (!Ext4ExtentHeaderValid (ExtHeader, MaxExtentsPerNode)) { > > FreePool (Buffer); > > return EFI_VOLUME_CORRUPTED; > > } > > -- > > 2.40.1 > > >
-- Pedro -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#104421): https://edk2.groups.io/g/devel/message/104421 Mute This Topic: https://groups.io/mt/98786841/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-