public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements
@ 2022-12-09 16:10 Savva Mitrofanov
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 01/12] Ext4Pkg: Fix memory leak in Ext4RetrieveDirent Savva Mitrofanov
                   ` (12 more replies)
  0 siblings, 13 replies; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-09 16:10 UTC (permalink / raw)
  To: devel; +Cc: Marvin Häuser, Pedro Falcato, Vitaly Cheptsov

Hi all,

This patchset fixes several code problems found by fuzzing Ext4Dxe like
buffer and integer overflows, memory leaks, logic bugs and so on.

REF: https://github.com/savvamitrofanov/edk2-platforms/tree/master

Cc: Marvin Häuser <mhaeuser@posteo.de>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Vitaly Cheptsov <vit9696@protonmail.com>

Savva Mitrofanov (12):
  Ext4Pkg: Fix memory leak in Ext4RetrieveDirent
  Ext4Pkg: Move EXT4_NAME_MAX definition to Ext4Disk.h
  Ext4Pkg: Fix global buffer overflow in Ext4ReadDir
  Ext4Pkg: Fix incorrect checksum metadata feature check
  Ext4Pkg: Fix division by zero by adding check for s_inodes_per_group
  Ext4Pkg: Add comparison between Position and FileSize in
    Ext4SetPosition
  Ext4Pkg: Add inode number validity check
  Ext4Pkg: Fix shift out of bounds in Ext4OpenSuperblock
  Ext4Pkg: Correct integer overflow check on multiplication in DiskUtil
  Ext4Pkg: Check that source file is directory in Ext4OpenInternal
  Ext4Pkg: Check VolumeName allocation correctness in Ext4GetVolumeName
  Ext4Pkg: Add missing exit Status in Ext4OpenDirent

 Features/Ext4Pkg/Ext4Pkg.dsc          |  2 +-
 Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h   | 17 +++++-
 Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h    | 59 ++++++++++++++++----
 Features/Ext4Pkg/Ext4Dxe/BlockGroup.c |  5 ++
 Features/Ext4Pkg/Ext4Dxe/Directory.c  | 51 ++++++++++-------
 Features/Ext4Pkg/Ext4Dxe/DiskUtil.c   |  8 +--
 Features/Ext4Pkg/Ext4Dxe/File.c       | 44 ++++++++++-----
 Features/Ext4Pkg/Ext4Dxe/Inode.c      |  2 +-
 Features/Ext4Pkg/Ext4Dxe/Superblock.c | 16 ++++--
 9 files changed, 147 insertions(+), 57 deletions(-)

-- 
2.38.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [edk2-platforms][PATCH v1 01/12] Ext4Pkg: Fix memory leak in Ext4RetrieveDirent
  2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
@ 2022-12-09 16:10 ` Savva Mitrofanov
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 02/12] Ext4Pkg: Move EXT4_NAME_MAX definition to Ext4Disk.h Savva Mitrofanov
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-09 16:10 UTC (permalink / raw)
  To: devel; +Cc: Marvin Häuser, Pedro Falcato, Vitaly Cheptsov

We need to free buffer on return if BlockRemainder != 0. Also changed
return logic from function to use use common exit to prevent code
duplication.

Cc: Marvin Häuser <mhaeuser@posteo.de>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Vitaly Cheptsov <vit9696@protonmail.com>
Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
---
 Features/Ext4Pkg/Ext4Dxe/Directory.c | 30 +++++++++++---------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/Features/Ext4Pkg/Ext4Dxe/Directory.c b/Features/Ext4Pkg/Ext4Dxe/Directory.c
index 4441e6d192b6..8b8fce568e43 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Directory.c
+++ b/Features/Ext4Pkg/Ext4Dxe/Directory.c
@@ -112,8 +112,7 @@ Ext4RetrieveDirent (
   UINTN           ToCopy;
   UINTN           BlockOffset;
 
-  Status = EFI_NOT_FOUND;
-  Buf    = AllocatePool (Partition->BlockSize);
+  Buf = AllocatePool (Partition->BlockSize);
 
   if (Buf == NULL) {
     return EFI_OUT_OF_RESOURCES;
@@ -127,7 +126,8 @@ Ext4RetrieveDirent (
   DivU64x32Remainder (DirInoSize, Partition->BlockSize, &BlockRemainder);
   if (BlockRemainder != 0) {
     // Directory inodes need to have block aligned sizes
-    return EFI_VOLUME_CORRUPTED;
+    Status = EFI_VOLUME_CORRUPTED;
+    goto Out;
   }
 
   while (Off < DirInoSize) {
@@ -136,8 +136,7 @@ Ext4RetrieveDirent (
     Status = Ext4Read (Partition, Directory, Buf, Off, &Length);
 
     if (Status != EFI_SUCCESS) {
-      FreePool (Buf);
-      return Status;
+      goto Out;
     }
 
     for (BlockOffset = 0; BlockOffset < Partition->BlockSize; ) {
@@ -145,19 +144,19 @@ Ext4RetrieveDirent (
       RemainingBlock = Partition->BlockSize - BlockOffset;
       // Check if the minimum directory entry fits inside [BlockOffset, EndOfBlock]
       if (RemainingBlock < EXT4_MIN_DIR_ENTRY_LEN) {
-        FreePool (Buf);
-        return EFI_VOLUME_CORRUPTED;
+        Status = EFI_VOLUME_CORRUPTED;
+        goto Out;
       }
 
       if (!Ext4ValidDirent (Entry)) {
-        FreePool (Buf);
-        return EFI_VOLUME_CORRUPTED;
+        Status = EFI_VOLUME_CORRUPTED;
+        goto Out;
       }
 
       if ((Entry->name_len > RemainingBlock) || (Entry->rec_len > RemainingBlock)) {
         // Corrupted filesystem
-        FreePool (Buf);
-        return EFI_VOLUME_CORRUPTED;
+        Status = EFI_VOLUME_CORRUPTED;
+        goto Out;
       }
 
       // Unused entry
@@ -186,8 +185,8 @@ Ext4RetrieveDirent (
         ToCopy = MIN (Entry->rec_len, sizeof (EXT4_DIR_ENTRY));
 
         CopyMem (Result, Entry, ToCopy);
-        FreePool (Buf);
-        return EFI_SUCCESS;
+        Status = EFI_SUCCESS;
+        goto Out;
       }
 
       BlockOffset += Entry->rec_len;
@@ -196,8 +195,11 @@ Ext4RetrieveDirent (
     Off += Partition->BlockSize;
   }
 
+  Status = EFI_NOT_FOUND;
+
+Out:
   FreePool (Buf);
-  return EFI_NOT_FOUND;
+  return Status;
 }
 
 /**
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [edk2-platforms][PATCH v1 02/12] Ext4Pkg: Move EXT4_NAME_MAX definition to Ext4Disk.h
  2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 01/12] Ext4Pkg: Fix memory leak in Ext4RetrieveDirent Savva Mitrofanov
@ 2022-12-09 16:10 ` Savva Mitrofanov
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 03/12] Ext4Pkg: Fix global buffer overflow in Ext4ReadDir Savva Mitrofanov
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-09 16:10 UTC (permalink / raw)
  To: devel; +Cc: Marvin Häuser, Pedro Falcato, Vitaly Cheptsov

Constant EXT4_NAME_MAX is related to EXT4_DIR_ENTRY FS structure, so it
should be placed into Ext4Disk.h header

Cc: Marvin Häuser <mhaeuser@posteo.de>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Vitaly Cheptsov <vit9696@protonmail.com>
Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
---
 Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h | 4 +++-
 Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h  | 1 -
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h b/Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h
index 4fd91a423324..1285644dcb25 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h
+++ b/Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h
@@ -397,12 +397,14 @@ typedef struct _Ext4Inode {
   UINT32       i_projid;
 } EXT4_INODE;
 
+#define EXT4_NAME_MAX 255
+
 typedef struct {
   UINT32    inode;
   UINT16    rec_len;
   UINT8     name_len;
   UINT8     file_type;
-  CHAR8     name[255];
+  CHAR8     name[EXT4_NAME_MAX];
 } EXT4_DIR_ENTRY;
 
 #define EXT4_MIN_DIR_ENTRY_LEN  8
diff --git a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h
index adf3c13f6ea9..dde4f4cb0e06 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h
+++ b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h
@@ -32,7 +32,6 @@
 #include "Ext4Disk.h"
 
 #define SYMLOOP_MAX    8
-#define EXT4_NAME_MAX  255
 //
 // We need to specify path length limit for security purposes, to prevent possible
 // overflows and dead-loop conditions. Originally this limit is absent in FS design,
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [edk2-platforms][PATCH v1 03/12] Ext4Pkg: Fix global buffer overflow in Ext4ReadDir
  2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 01/12] Ext4Pkg: Fix memory leak in Ext4RetrieveDirent Savva Mitrofanov
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 02/12] Ext4Pkg: Move EXT4_NAME_MAX definition to Ext4Disk.h Savva Mitrofanov
@ 2022-12-09 16:10 ` Savva Mitrofanov
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 04/12] Ext4Pkg: Fix incorrect checksum metadata feature check Savva Mitrofanov
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-09 16:10 UTC (permalink / raw)
  To: devel; +Cc: Marvin Häuser, Pedro Falcato, Vitaly Cheptsov

Directory entry structure can contain name_len bigger than size of "."
or "..", that's why CompareMem in such cases leads to global buffer
overflow. So there are two problems. The first is that statement doesn't
check cases when name_len != 0 but > 2 and the second is that we passing
big Length to CompareMem routine.
The correct way here is to check that name_len <= 2 and check for
null-terminator presence

Cc: Marvin Häuser <mhaeuser@posteo.de>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Vitaly Cheptsov <vit9696@protonmail.com>
Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
---
 Features/Ext4Pkg/Ext4Dxe/Directory.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/Features/Ext4Pkg/Ext4Dxe/Directory.c b/Features/Ext4Pkg/Ext4Dxe/Directory.c
index 8b8fce568e43..ffc0e8043076 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Directory.c
+++ b/Features/Ext4Pkg/Ext4Dxe/Directory.c
@@ -491,11 +491,9 @@ Ext4ReadDir (
 
     // Entry.name_len may be 0 if it's a nameless entry, like an unused entry
     // or a checksum at the end of the directory block.
-    // memcmp (and CompareMem) return 0 when the passed length is 0.
-
-    IsDotOrDotDot = Entry.name_len != 0 &&
-                    (CompareMem (Entry.name, ".", Entry.name_len) == 0 ||
-                     CompareMem (Entry.name, "..", Entry.name_len) == 0);
+    IsDotOrDotDot = Entry.name_len <= 2 &&
+                    ((Entry.name[0] == '.') &&
+                     (Entry.name[1] == '.' || Entry.name[1] == '\0'));
 
     // When inode = 0, it's unused.
     ShouldSkip = Entry.inode == 0 || IsDotOrDotDot;
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [edk2-platforms][PATCH v1 04/12] Ext4Pkg: Fix incorrect checksum metadata feature check
  2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
                   ` (2 preceding siblings ...)
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 03/12] Ext4Pkg: Fix global buffer overflow in Ext4ReadDir Savva Mitrofanov
@ 2022-12-09 16:10 ` Savva Mitrofanov
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 05/12] Ext4Pkg: Fix division by zero by adding check for s_inodes_per_group Savva Mitrofanov
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-09 16:10 UTC (permalink / raw)
  To: devel; +Cc: Marvin Häuser, Pedro Falcato, Vitaly Cheptsov

Missing comparison != 0 leads to broken logic condition. Also replaced
CSUM_SEED feature_incompat check with predefined macro EXT4_HAS_INCOMPAT

Cc: Marvin Häuser <mhaeuser@posteo.de>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Vitaly Cheptsov <vit9696@protonmail.com>
Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
---
 Features/Ext4Pkg/Ext4Dxe/Superblock.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/Features/Ext4Pkg/Ext4Dxe/Superblock.c b/Features/Ext4Pkg/Ext4Dxe/Superblock.c
index edee051c41e8..4c662bd1784f 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Superblock.c
+++ b/Features/Ext4Pkg/Ext4Dxe/Superblock.c
@@ -220,13 +220,11 @@ Ext4OpenSuperblock (
   }
 
   // At the time of writing, it's the only supported checksum.
-  if (Partition->FeaturesCompat & EXT4_FEATURE_RO_COMPAT_METADATA_CSUM &&
-      (Sb->s_checksum_type != EXT4_CHECKSUM_CRC32C))
-  {
+  if (EXT4_HAS_METADATA_CSUM (Partition) && (Sb->s_checksum_type != EXT4_CHECKSUM_CRC32C)) {
     return EFI_UNSUPPORTED;
   }
 
-  if ((Partition->FeaturesIncompat & EXT4_FEATURE_INCOMPAT_CSUM_SEED) != 0) {
+  if (EXT4_HAS_INCOMPAT (Partition, EXT4_FEATURE_INCOMPAT_CSUM_SEED)) {
     Partition->InitialSeed = Sb->s_checksum_seed;
   } else {
     Partition->InitialSeed = Ext4CalculateChecksum (Partition, Sb->s_uuid, 16, ~0U);
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [edk2-platforms][PATCH v1 05/12] Ext4Pkg: Fix division by zero by adding check for s_inodes_per_group
  2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
                   ` (3 preceding siblings ...)
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 04/12] Ext4Pkg: Fix incorrect checksum metadata feature check Savva Mitrofanov
@ 2022-12-09 16:10 ` Savva Mitrofanov
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 06/12] Ext4Pkg: Add comparison between Position and FileSize in Ext4SetPosition Savva Mitrofanov
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-09 16:10 UTC (permalink / raw)
  To: devel; +Cc: Marvin Häuser, Pedro Falcato, Vitaly Cheptsov

Superblock s_inodes_per_group field can't be zero, it leads to division
by zero in BlockGroup routine Ext4ReadInode

Cc: Marvin Häuser <mhaeuser@posteo.de>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Vitaly Cheptsov <vit9696@protonmail.com>
Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
---
 Features/Ext4Pkg/Ext4Dxe/Superblock.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Features/Ext4Pkg/Ext4Dxe/Superblock.c b/Features/Ext4Pkg/Ext4Dxe/Superblock.c
index 4c662bd1784f..adaf475ea54d 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Superblock.c
+++ b/Features/Ext4Pkg/Ext4Dxe/Superblock.c
@@ -243,6 +243,11 @@ Ext4OpenSuperblock (
 
   DEBUG ((DEBUG_FS, "Read only = %u\n", Partition->ReadOnly));
 
+  if (Sb->s_inodes_per_group == 0) {
+    DEBUG ((DEBUG_ERROR, "[ext4] Inodes per group can not be zero\n"));
+    return EFI_VOLUME_CORRUPTED;
+  }
+
   Partition->BlockSize = (UINT32)LShiftU64 (1024, Sb->s_log_block_size);
 
   // The size of a block group can also be calculated as 8 * Partition->BlockSize
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [edk2-platforms][PATCH v1 06/12] Ext4Pkg: Add comparison between Position and FileSize in Ext4SetPosition
  2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
                   ` (4 preceding siblings ...)
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 05/12] Ext4Pkg: Fix division by zero by adding check for s_inodes_per_group Savva Mitrofanov
@ 2022-12-09 16:10 ` Savva Mitrofanov
  2022-12-09 22:12   ` Pedro Falcato
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 07/12] Ext4Pkg: Add inode number validity check Savva Mitrofanov
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-09 16:10 UTC (permalink / raw)
  To: devel; +Cc: Marvin Häuser, Pedro Falcato, Vitaly Cheptsov

Missing such comparison leads to infinite loop states, for example code
which trying to read entire file can easily get out of bound of
file size by passing position value which exceeds file size without this
check. So we need to add there missing comparison between the desired
position to be set and file size

Cc: Marvin Häuser <mhaeuser@posteo.de>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Vitaly Cheptsov <vit9696@protonmail.com>
Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
---
 Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h | 19 +++++++++---------
 Features/Ext4Pkg/Ext4Dxe/File.c    | 21 +++++++++++++-------
 2 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h
index dde4f4cb0e06..1dcb644e3b35 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h
+++ b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h
@@ -31,7 +31,7 @@
 
 #include "Ext4Disk.h"
 
-#define SYMLOOP_MAX    8
+#define SYMLOOP_MAX  8
 //
 // We need to specify path length limit for security purposes, to prevent possible
 // overflows and dead-loop conditions. Originally this limit is absent in FS design,
@@ -715,16 +715,15 @@ Ext4GetPosition (
 /**
   Sets a file's current position.
 
-  @param[in]  This            A pointer to the EFI_FILE_PROTOCOL instance that
-is the file handle to set the requested position on.
-  @param[in] Position        The byte position from the start of the file to
-set.
+  @param[in]  This            A pointer to the EFI_FILE_PROTOCOL instance that is the
+                              file handle to set the requested position on.
+  @param[in]  Position        The byte position from the start of the file to set.
 
-  @retval EFI_SUCCESS      The position was set.
-  @retval EFI_UNSUPPORTED  The seek request for nonzero is not valid on open
-                           directories.
-  @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted
-file.
+  @retval EFI_SUCCESS            The position was set.
+  @retval EFI_INVALID_PARAMETER  The seek request for non-zero position is not valid on open
+                                 directories.
+  @retval EFI_UNSUPPORTED        The seek request for position is exceeds FileSize.
+  @retval EFI_DEVICE_ERROR       An attempt was made to set the position of a deleted file.
 
 **/
 EFI_STATUS
diff --git a/Features/Ext4Pkg/Ext4Dxe/File.c b/Features/Ext4Pkg/Ext4Dxe/File.c
index 04198a53bfc0..b4ed78847258 100644
--- a/Features/Ext4Pkg/Ext4Dxe/File.c
+++ b/Features/Ext4Pkg/Ext4Dxe/File.c
@@ -587,12 +587,13 @@ Ext4GetPosition (
 
   @param[in]  This            A pointer to the EFI_FILE_PROTOCOL instance that is the
                               file handle to set the requested position on.
-  @param[in] Position        The byte position from the start of the file to set.
+  @param[in]  Position        The byte position from the start of the file to set.
 
-  @retval EFI_SUCCESS      The position was set.
-  @retval EFI_UNSUPPORTED  The seek request for nonzero is not valid on open
-                           directories.
-  @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file.
+  @retval EFI_SUCCESS            The position was set.
+  @retval EFI_INVALID_PARAMETER  The seek request for non-zero position is not valid on open
+                                 directories.
+  @retval EFI_UNSUPPORTED        The seek request for position is exceeds FileSize.
+  @retval EFI_DEVICE_ERROR       An attempt was made to set the position of a deleted file.
 
 **/
 EFI_STATUS
@@ -603,17 +604,23 @@ Ext4SetPosition (
   )
 {
   EXT4_FILE  *File;
+  UINT64     FileSize;
 
   File = EXT4_FILE_FROM_THIS (This);
 
   // Only seeks to 0 (so it resets the ReadDir operation) are allowed
   if (Ext4FileIsDir (File) && (Position != 0)) {
-    return EFI_UNSUPPORTED;
+    return EFI_INVALID_PARAMETER;
   }
 
+  FileSize = EXT4_INODE_SIZE (File->Inode);
+
   // -1 (0xffffff.......) seeks to the end of the file
   if (Position == (UINT64)-1) {
-    Position = EXT4_INODE_SIZE (File->Inode);
+    Position = FileSize;
+  } else if (Position > FileSize) {
+    DEBUG ((DEBUG_FS, "[ext4] Ext4SetPosition Cannot seek to #%Lx of %Lx\n", Position, FileSize));
+    return EFI_UNSUPPORTED;
   }
 
   File->Position = Position;
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [edk2-platforms][PATCH v1 07/12] Ext4Pkg: Add inode number validity check
  2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
                   ` (5 preceding siblings ...)
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 06/12] Ext4Pkg: Add comparison between Position and FileSize in Ext4SetPosition Savva Mitrofanov
@ 2022-12-09 16:10 ` Savva Mitrofanov
  2022-12-09 16:11 ` [edk2-platforms][PATCH v1 08/12] Ext4Pkg: Fix shift out of bounds in Ext4OpenSuperblock Savva Mitrofanov
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-09 16:10 UTC (permalink / raw)
  To: devel; +Cc: Marvin Häuser, Pedro Falcato, Vitaly Cheptsov

We need to validate inode number to prevent possible null-pointer
dereference of directory parent in Ext4OpenDirent. Also checks that
inode number valid across opened partition before we read it in
Ext4ReadInode.

Cc: Marvin Häuser <mhaeuser@posteo.de>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Vitaly Cheptsov <vit9696@protonmail.com>
Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
---
 Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h   | 15 +++++++++---
 Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h    | 25 ++++++++++++++++++++
 Features/Ext4Pkg/Ext4Dxe/BlockGroup.c |  5 ++++
 Features/Ext4Pkg/Ext4Dxe/Directory.c  | 10 ++++++++
 4 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h b/Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h
index 1285644dcb25..6b56ce6813fc 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h
+++ b/Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h
@@ -397,7 +397,7 @@ typedef struct _Ext4Inode {
   UINT32       i_projid;
 } EXT4_INODE;
 
-#define EXT4_NAME_MAX 255
+#define EXT4_NAME_MAX  255
 
 typedef struct {
   UINT32    inode;
@@ -469,8 +469,17 @@ typedef UINT64  EXT4_BLOCK_NR;
 typedef UINT32  EXT2_BLOCK_NR;
 typedef UINT32  EXT4_INO_NR;
 
-// 2 is always the root inode number in ext4
-#define EXT4_ROOT_INODE_NR  2
+/* Special inode numbers */
+#define EXT4_ROOT_INODE_NR         2
+#define EXT4_USR_QUOTA_INODE_NR    3
+#define EXT4_GRP_QUOTA_INODE_NR    4
+#define EXT4_BOOT_LOADER_INODE_NR  5
+#define EXT4_UNDEL_DIR_INODE_NR    6
+#define EXT4_RESIZE_INODE_NR       7
+#define EXT4_JOURNAL_INODE_NR      8
+
+/* First non-reserved inode for old ext4 filesystems */
+#define EXT4_GOOD_OLD_FIRST_INODE_NR  11
 
 #define EXT4_BLOCK_FILE_HOLE  0
 
diff --git a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h
index 1dcb644e3b35..d135892633af 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h
+++ b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h
@@ -287,6 +287,31 @@ Ext4GetBlockGroupDesc (
   IN UINT32          BlockGroup
   );
 
+/**
+   Retrieves the first usable non-reserved inode number from the superblock
+   of the opened partition.
+
+   @param[in]  Partition      Pointer to the opened ext4 partition.
+
+   @return The first usable inode number (non-reserved).
+**/
+#define EXT4_FIRST_INODE_NR(Partition)                                         \
+  ((Partition->SuperBlock.s_rev_level == EXT4_GOOD_OLD_REV) ?                  \
+         EXT4_GOOD_OLD_FIRST_INODE_NR :                                        \
+         Partition->SuperBlock.s_first_ino)
+
+/**
+   Checks inode number validity across superblock of the opened partition.
+
+   @param[in]  Partition      Pointer to the opened ext4 partition.
+
+   @return TRUE if inode number is valid.
+**/
+#define EXT4_IS_VALID_INODE_NR(Partition, InodeNum)                            \
+  (InodeNum == EXT4_ROOT_INODE_NR ||                                           \
+        (InodeNum >= EXT4_FIRST_INODE_NR(Partition) &&                         \
+         InodeNum <= Partition->SuperBlock.s_inodes_count))
+
 /**
    Reads an inode from disk.
 
diff --git a/Features/Ext4Pkg/Ext4Dxe/BlockGroup.c b/Features/Ext4Pkg/Ext4Dxe/BlockGroup.c
index cba96cd95afc..f34cdc5dbad7 100644
--- a/Features/Ext4Pkg/Ext4Dxe/BlockGroup.c
+++ b/Features/Ext4Pkg/Ext4Dxe/BlockGroup.c
@@ -50,6 +50,11 @@ Ext4ReadInode (
   EXT4_BLOCK_NR          InodeTableStart;
   EFI_STATUS             Status;
 
+  if (!EXT4_IS_VALID_INODE_NR (Partition, InodeNum)) {
+    DEBUG ((DEBUG_ERROR, "[ext4] Error reading inode: inode number %lu isn't valid\n", InodeNum));
+    return EFI_VOLUME_CORRUPTED;
+  }
+
   BlockGroupNumber = (UINT32)DivU64x64Remainder (
                                InodeNum - 1,
                                Partition->SuperBlock.s_inodes_per_group,
diff --git a/Features/Ext4Pkg/Ext4Dxe/Directory.c b/Features/Ext4Pkg/Ext4Dxe/Directory.c
index ffc0e8043076..ff476c8641e8 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Directory.c
+++ b/Features/Ext4Pkg/Ext4Dxe/Directory.c
@@ -163,6 +163,10 @@ Ext4RetrieveDirent (
       if (Entry->inode == 0) {
         BlockOffset += Entry->rec_len;
         continue;
+      } else if (!EXT4_IS_VALID_INODE_NR (Partition, Entry->inode)) {
+        DEBUG ((DEBUG_ERROR, "[ext4] Ext4RetrieveDirent directory entry inode number %u isn't valid\n", Entry->inode));
+        Status = EFI_VOLUME_CORRUPTED;
+        goto Out;
       }
 
       Status = Ext4GetUcs2DirentName (Entry, DirentUcs2Name);
@@ -498,6 +502,12 @@ Ext4ReadDir (
     // When inode = 0, it's unused.
     ShouldSkip = Entry.inode == 0 || IsDotOrDotDot;
 
+    if ((Entry.inode != 0) && !EXT4_IS_VALID_INODE_NR (Partition, Entry.inode)) {
+      DEBUG ((DEBUG_ERROR, "[ext4] Ext4ReadDir directory entry inode number %u isn't valid\n", Entry.inode));
+      Status = EFI_VOLUME_CORRUPTED;
+      goto Out;
+    }
+
     if (ShouldSkip) {
       Offset += Entry.rec_len;
       continue;
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [edk2-platforms][PATCH v1 08/12] Ext4Pkg: Fix shift out of bounds in Ext4OpenSuperblock
  2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
                   ` (6 preceding siblings ...)
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 07/12] Ext4Pkg: Add inode number validity check Savva Mitrofanov
@ 2022-12-09 16:11 ` Savva Mitrofanov
  2022-12-09 16:11 ` [edk2-platforms][PATCH v1 09/12] Ext4Pkg: Correct integer overflow check on multiplication in DiskUtil Savva Mitrofanov
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-09 16:11 UTC (permalink / raw)
  To: devel; +Cc: Marvin Häuser, Pedro Falcato, Vitaly Cheptsov

Missing check for wrong s_log_block_size exponent leads to shift out of
bounds. Limit block size to 2 MiB

Cc: Marvin Häuser <mhaeuser@posteo.de>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Vitaly Cheptsov <vit9696@protonmail.com>
Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
---
 Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h    | 14 ++++++++++++++
 Features/Ext4Pkg/Ext4Dxe/Superblock.c |  5 +++++
 2 files changed, 19 insertions(+)

diff --git a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h
index d135892633af..0600a75d6750 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h
+++ b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h
@@ -40,6 +40,20 @@
 #define EXT4_EFI_PATH_MAX    4096
 #define EXT4_DRIVER_VERSION  0x0000
 
+//
+// The EXT4 Specification doesn't strictly limit block size and this value could be up to 2^31,
+// but in practice it is limited by PAGE_SIZE due to performance significant impact.
+// Many EXT4 implementations have size of block limited to PAGE_SIZE. In many cases it's limited
+// to 4096, which is a commonly supported page size on most MMU-capable hardware, and up to 65536.
+// So, to take a balance between compatibility and security measures, it is decided to use the
+// value of 2MiB as the limit, which is equal to page size on new hardware.
+// As for supporting big block sizes, EXT4 has a RO_COMPAT_FEATURE called BIGALLOC, which changes
+// EXT4 to use clustered allocation, so that each bit in the ext4 block allocation bitmap addresses
+// a power of two number of blocks. So it would be wiser to implement and use this feature
+// if there is such a need instead of big block size.
+//
+#define EXT4_LOG_BLOCK_SIZE_MAX  11
+
 /**
    Opens an ext4 partition and installs the Simple File System protocol.
 
diff --git a/Features/Ext4Pkg/Ext4Dxe/Superblock.c b/Features/Ext4Pkg/Ext4Dxe/Superblock.c
index adaf475ea54d..ffe66a8bb847 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Superblock.c
+++ b/Features/Ext4Pkg/Ext4Dxe/Superblock.c
@@ -248,6 +248,11 @@ Ext4OpenSuperblock (
     return EFI_VOLUME_CORRUPTED;
   }
 
+  if (Sb->s_log_block_size > EXT4_LOG_BLOCK_SIZE_MAX) {
+    DEBUG ((DEBUG_ERROR, "[ext4] SuperBlock s_log_block_size %lu is too big\n", Sb->s_log_block_size));
+    return EFI_UNSUPPORTED;
+  }
+
   Partition->BlockSize = (UINT32)LShiftU64 (1024, Sb->s_log_block_size);
 
   // The size of a block group can also be calculated as 8 * Partition->BlockSize
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [edk2-platforms][PATCH v1 09/12] Ext4Pkg: Correct integer overflow check on multiplication in DiskUtil
  2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
                   ` (7 preceding siblings ...)
  2022-12-09 16:11 ` [edk2-platforms][PATCH v1 08/12] Ext4Pkg: Fix shift out of bounds in Ext4OpenSuperblock Savva Mitrofanov
@ 2022-12-09 16:11 ` Savva Mitrofanov
  2022-12-09 22:16   ` Pedro Falcato
  2022-12-09 16:11 ` [edk2-platforms][PATCH v1 10/12] Ext4Pkg: Check that source file is directory in Ext4OpenInternal Savva Mitrofanov
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-09 16:11 UTC (permalink / raw)
  To: devel; +Cc: Marvin Häuser, Pedro Falcato, Vitaly Cheptsov

Multiplication overflow could result into small numbers, so we need also
check it

Cc: Marvin Häuser <mhaeuser@posteo.de>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Vitaly Cheptsov <vit9696@protonmail.com>
Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
---
 Features/Ext4Pkg/Ext4Pkg.dsc        | 2 +-
 Features/Ext4Pkg/Ext4Dxe/DiskUtil.c | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/Features/Ext4Pkg/Ext4Pkg.dsc b/Features/Ext4Pkg/Ext4Pkg.dsc
index 59bc327ebf6e..621c63eaf92d 100644
--- a/Features/Ext4Pkg/Ext4Pkg.dsc
+++ b/Features/Ext4Pkg/Ext4Pkg.dsc
@@ -46,7 +46,7 @@
   DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
   OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
   BaseUcs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
-  
+
   #
   # Required for stack protector support
   #
diff --git a/Features/Ext4Pkg/Ext4Dxe/DiskUtil.c b/Features/Ext4Pkg/Ext4Dxe/DiskUtil.c
index 32da35f7d9f5..c4af956da926 100644
--- a/Features/Ext4Pkg/Ext4Dxe/DiskUtil.c
+++ b/Features/Ext4Pkg/Ext4Dxe/DiskUtil.c
@@ -60,11 +60,11 @@ Ext4ReadBlocks (
   // Check for overflow on the block -> byte conversions.
   // Partition->BlockSize is never 0, so we don't need to check for that.
 
-  if (Offset > DivU64x32 ((UINT64)-1, Partition->BlockSize)) {
+  if ((NumberBlocks != 0) && (DivU64x64Remainder (Offset, BlockNumber, NULL) != Partition->BlockSize)) {
     return EFI_INVALID_PARAMETER;
   }
 
-  if (Length > (UINTN)-1/Partition->BlockSize) {
+  if ((NumberBlocks != 0) && (Length / NumberBlocks != Partition->BlockSize)) {
     return EFI_INVALID_PARAMETER;
   }
 
@@ -94,12 +94,12 @@ Ext4AllocAndReadBlocks (
 
   Length = NumberBlocks * Partition->BlockSize;
 
-  if (Length > (UINTN)-1/Partition->BlockSize) {
+  // Check for integer overflow
+  if ((NumberBlocks != 0) && (Length / NumberBlocks != Partition->BlockSize)) {
     return NULL;
   }
 
   Buf = AllocatePool (Length);
-
   if (Buf == NULL) {
     return NULL;
   }
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [edk2-platforms][PATCH v1 10/12] Ext4Pkg: Check that source file is directory in Ext4OpenInternal
  2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
                   ` (8 preceding siblings ...)
  2022-12-09 16:11 ` [edk2-platforms][PATCH v1 09/12] Ext4Pkg: Correct integer overflow check on multiplication in DiskUtil Savva Mitrofanov
@ 2022-12-09 16:11 ` Savva Mitrofanov
  2022-12-09 16:11 ` [edk2-platforms][PATCH v1 11/12] Ext4Pkg: Check VolumeName allocation correctness in Ext4GetVolumeName Savva Mitrofanov
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-09 16:11 UTC (permalink / raw)
  To: devel; +Cc: Marvin Häuser, Pedro Falcato, Vitaly Cheptsov

This check already present in the while loop below, but absent for cases
when input file is nameless, so to handle assertion in Ext4ReadFile we
need to add it at the top of function

Cc: Marvin Häuser <mhaeuser@posteo.de>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Vitaly Cheptsov <vit9696@protonmail.com>
Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
---
 Features/Ext4Pkg/Ext4Dxe/File.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/Features/Ext4Pkg/Ext4Dxe/File.c b/Features/Ext4Pkg/Ext4Dxe/File.c
index b4ed78847258..2d76e1818021 100644
--- a/Features/Ext4Pkg/Ext4Dxe/File.c
+++ b/Features/Ext4Pkg/Ext4Dxe/File.c
@@ -207,6 +207,11 @@ Ext4OpenInternal (
   Level     = 0;
 
   DEBUG ((DEBUG_FS, "[ext4] Ext4OpenInternal %s\n", FileName));
+
+  if (!Ext4FileIsDir (Current)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
   // If the path starts with a backslash, we treat the root directory as the base directory
   if (FileName[0] == L'\\') {
     FileName++;
@@ -219,6 +224,10 @@ Ext4OpenInternal (
       return EFI_ACCESS_DENIED;
     }
 
+    if (!Ext4FileIsDir (Current)) {
+      return EFI_INVALID_PARAMETER;
+    }
+
     // Discard leading path separators
     while (FileName[0] == L'\\') {
       FileName++;
@@ -242,10 +251,6 @@ Ext4OpenInternal (
 
     DEBUG ((DEBUG_FS, "[ext4] Opening %s\n", PathSegment));
 
-    if (!Ext4FileIsDir (Current)) {
-      return EFI_INVALID_PARAMETER;
-    }
-
     if (!Ext4IsLastPathSegment (FileName)) {
       if (!Ext4DirCanLookup (Current)) {
         return EFI_ACCESS_DENIED;
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [edk2-platforms][PATCH v1 11/12] Ext4Pkg: Check VolumeName allocation correctness in Ext4GetVolumeName
  2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
                   ` (9 preceding siblings ...)
  2022-12-09 16:11 ` [edk2-platforms][PATCH v1 10/12] Ext4Pkg: Check that source file is directory in Ext4OpenInternal Savva Mitrofanov
@ 2022-12-09 16:11 ` Savva Mitrofanov
  2022-12-09 16:11 ` [edk2-platforms][PATCH v1 12/12] Ext4Pkg: Add missing exit Status in Ext4OpenDirent Savva Mitrofanov
  2022-12-09 22:28 ` [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Pedro Falcato
  12 siblings, 0 replies; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-09 16:11 UTC (permalink / raw)
  To: devel; +Cc: Marvin Häuser, Pedro Falcato, Vitaly Cheptsov

Missing check in some cases leads to failed StrCpyS call in
Ext4GetVolumeLabelInfo. Also correct condition that checks Inode pointer
for being NULL in Ext4AllocateInode

Cc: Marvin Häuser <mhaeuser@posteo.de>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Vitaly Cheptsov <vit9696@protonmail.com>
Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
---
 Features/Ext4Pkg/Ext4Dxe/File.c  | 10 ++++++++--
 Features/Ext4Pkg/Ext4Dxe/Inode.c |  2 +-
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/Features/Ext4Pkg/Ext4Dxe/File.c b/Features/Ext4Pkg/Ext4Dxe/File.c
index 2d76e1818021..7939fcd3acef 100644
--- a/Features/Ext4Pkg/Ext4Dxe/File.c
+++ b/Features/Ext4Pkg/Ext4Dxe/File.c
@@ -726,7 +726,11 @@ Ext4GetVolumeName (
 
     VolNameLength = StrLen (VolumeName);
   } else {
-    VolumeName    = AllocateZeroPool (sizeof (CHAR16));
+    VolumeName = AllocateZeroPool (sizeof (CHAR16));
+    if (VolumeName == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
     VolNameLength = 0;
   }
 
@@ -793,7 +797,9 @@ Ext4GetFilesystemInfo (
   Info->VolumeSize = MultU64x32 (TotalBlocks, Part->BlockSize);
   Info->FreeSpace  = MultU64x32 (FreeBlocks, Part->BlockSize);
 
-  StrCpyS (Info->VolumeLabel, VolNameLength + 1, VolumeName);
+  Status = StrCpyS (Info->VolumeLabel, VolNameLength + 1, VolumeName);
+
+  ASSERT_EFI_ERROR (Status);
 
   FreePool (VolumeName);
 
diff --git a/Features/Ext4Pkg/Ext4Dxe/Inode.c b/Features/Ext4Pkg/Ext4Dxe/Inode.c
index 5ccb4d2bfc42..2977238d687c 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Inode.c
+++ b/Features/Ext4Pkg/Ext4Dxe/Inode.c
@@ -230,7 +230,7 @@ Ext4AllocateInode (
 
   Inode = AllocateZeroPool (InodeSize);
 
-  if (!Inode) {
+  if (Inode == NULL) {
     return NULL;
   }
 
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [edk2-platforms][PATCH v1 12/12] Ext4Pkg: Add missing exit Status in Ext4OpenDirent
  2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
                   ` (10 preceding siblings ...)
  2022-12-09 16:11 ` [edk2-platforms][PATCH v1 11/12] Ext4Pkg: Check VolumeName allocation correctness in Ext4GetVolumeName Savva Mitrofanov
@ 2022-12-09 16:11 ` Savva Mitrofanov
  2022-12-09 22:28 ` [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Pedro Falcato
  12 siblings, 0 replies; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-09 16:11 UTC (permalink / raw)
  To: devel; +Cc: Marvin Häuser, Pedro Falcato, Vitaly Cheptsov

Missing EFI_OUT_OF_RESOURCES exit status on failed Ext4CreateDentry
leads to NULL-pointer dereference in Ext4GetFileInfo (passing NULL
buffer in Ext4ReadDir)

Cc: Marvin Häuser <mhaeuser@posteo.de>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Vitaly Cheptsov <vit9696@protonmail.com>
Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
---
 Features/Ext4Pkg/Ext4Dxe/Directory.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Features/Ext4Pkg/Ext4Dxe/Directory.c b/Features/Ext4Pkg/Ext4Dxe/Directory.c
index ff476c8641e8..efdce1477246 100644
--- a/Features/Ext4Pkg/Ext4Dxe/Directory.c
+++ b/Features/Ext4Pkg/Ext4Dxe/Directory.c
@@ -260,7 +260,8 @@ Ext4OpenDirent (
   } else {
     File->Dentry = Ext4CreateDentry (FileName, Directory->Dentry);
 
-    if (!File->Dentry) {
+    if (File->Dentry == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
       goto Error;
     }
   }
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [edk2-platforms][PATCH v1 06/12] Ext4Pkg: Add comparison between Position and FileSize in Ext4SetPosition
  2022-12-09 16:10 ` [edk2-platforms][PATCH v1 06/12] Ext4Pkg: Add comparison between Position and FileSize in Ext4SetPosition Savva Mitrofanov
@ 2022-12-09 22:12   ` Pedro Falcato
  2022-12-12 11:44     ` Savva Mitrofanov
  0 siblings, 1 reply; 18+ messages in thread
From: Pedro Falcato @ 2022-12-09 22:12 UTC (permalink / raw)
  To: Savva Mitrofanov; +Cc: devel, Marvin Häuser, Vitaly Cheptsov

[-- Attachment #1: Type: text/plain, Size: 1273 bytes --]

On Fri, Dec 9, 2022 at 4:11 PM Savva Mitrofanov <savvamtr@gmail.com> wrote:

> Missing such comparison leads to infinite loop states, for example code
> which trying to read entire file can easily get out of bound of
> file size by passing position value which exceeds file size without this
> check. So we need to add there missing comparison between the desired
> position to be set and file size
>
> +  FileSize = EXT4_INODE_SIZE (File->Inode);
> +
>    // -1 (0xffffff.......) seeks to the end of the file
>    if (Position == (UINT64)-1) {
> -    Position = EXT4_INODE_SIZE (File->Inode);
> +    Position = FileSize;
> +  } else if (Position > FileSize) {
> +    DEBUG ((DEBUG_FS, "[ext4] Ext4SetPosition Cannot seek to #%Lx of
> %Lx\n", Position, FileSize));
> +    return EFI_UNSUPPORTED;
>    }
>
>    File->Position = Position;
>

On further inspection, this case is covered in the UEFI spec.

https://uefi.org/specs/UEFI/2.10/13_Protocols_Media_Access.html#efi-file-protocol-read
says:

> EFI_DEVICE_ERROR     On entry, the current file position is beyond the
end of the file.

while the standard does not say SetPosition() can error out for bad seeks.

So I think we should allow this in SetPosition() and error out in Read().
Does this look good to you?

Pedro

[-- Attachment #2: Type: text/html, Size: 1945 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [edk2-platforms][PATCH v1 09/12] Ext4Pkg: Correct integer overflow check on multiplication in DiskUtil
  2022-12-09 16:11 ` [edk2-platforms][PATCH v1 09/12] Ext4Pkg: Correct integer overflow check on multiplication in DiskUtil Savva Mitrofanov
@ 2022-12-09 22:16   ` Pedro Falcato
  0 siblings, 0 replies; 18+ messages in thread
From: Pedro Falcato @ 2022-12-09 22:16 UTC (permalink / raw)
  To: Savva Mitrofanov; +Cc: devel, Marvin Häuser, Vitaly Cheptsov

[-- Attachment #1: Type: text/plain, Size: 304 bytes --]

On Fri, Dec 9, 2022 at 4:11 PM Savva Mitrofanov <savvamtr@gmail.com> wrote:

> Multiplication overflow could result into small numbers, so we need also
> check it
>

Can you fix the commit message? Overflow was (in theory) already getting
checked, I just did a remarkably poor job open-coding it.

Pedro

[-- Attachment #2: Type: text/html, Size: 668 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements
  2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
                   ` (11 preceding siblings ...)
  2022-12-09 16:11 ` [edk2-platforms][PATCH v1 12/12] Ext4Pkg: Add missing exit Status in Ext4OpenDirent Savva Mitrofanov
@ 2022-12-09 22:28 ` Pedro Falcato
  2022-12-12 14:40   ` Savva Mitrofanov
  12 siblings, 1 reply; 18+ messages in thread
From: Pedro Falcato @ 2022-12-09 22:28 UTC (permalink / raw)
  To: Savva Mitrofanov; +Cc: devel, Marvin Häuser, Vitaly Cheptsov

[-- Attachment #1: Type: text/plain, Size: 1810 bytes --]

On Fri, Dec 9, 2022 at 4:11 PM Savva Mitrofanov <savvamtr@gmail.com> wrote:

> Hi all,
>
> This patchset fixes several code problems found by fuzzing Ext4Dxe like
> buffer and integer overflows, memory leaks, logic bugs and so on.
>
> REF: https://github.com/savvamitrofanov/edk2-platforms/tree/master
>
> Cc: Marvin Häuser <mhaeuser@posteo.de>
> Cc: Pedro Falcato <pedro.falcato@gmail.com>
> Cc: Vitaly Cheptsov <vit9696@protonmail.com>
>
> Savva Mitrofanov (12):
>   Ext4Pkg: Fix memory leak in Ext4RetrieveDirent
>   Ext4Pkg: Move EXT4_NAME_MAX definition to Ext4Disk.h
>   Ext4Pkg: Fix global buffer overflow in Ext4ReadDir
>   Ext4Pkg: Fix incorrect checksum metadata feature check
>   Ext4Pkg: Fix division by zero by adding check for s_inodes_per_group
>   Ext4Pkg: Add comparison between Position and FileSize in
>     Ext4SetPosition
>   Ext4Pkg: Add inode number validity check
>   Ext4Pkg: Fix shift out of bounds in Ext4OpenSuperblock
>   Ext4Pkg: Correct integer overflow check on multiplication in DiskUtil
>   Ext4Pkg: Check that source file is directory in Ext4OpenInternal
>   Ext4Pkg: Check VolumeName allocation correctness in Ext4GetVolumeName
>   Ext4Pkg: Add missing exit Status in Ext4OpenDirent
>

Hi!

Thanks for the patches (and the fuzzing!). They all mostly lgtm, just some
small nits. Please fix them so I can test and merge.

Also, could you add a Fixes tag to each patch (like in the LKML and
elsewhere in OVMF) so we can more easily track what each patch fixes? Using
something simple like the oldest git blame of what you're fixing should be
enough in this case, no need for git bisect. I just want to establish a
good, clean track record here for me and for downstream users to better
know what they need to pick up!

Thanks,
Pedro

[-- Attachment #2: Type: text/html, Size: 2586 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [edk2-platforms][PATCH v1 06/12] Ext4Pkg: Add comparison between Position and FileSize in Ext4SetPosition
  2022-12-09 22:12   ` Pedro Falcato
@ 2022-12-12 11:44     ` Savva Mitrofanov
  0 siblings, 0 replies; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-12 11:44 UTC (permalink / raw)
  To: Pedro Falcato
  Cc: devel, mhaeuser,
	Виталий Юрьевич Чепцов

[-- Attachment #1: Type: text/plain, Size: 1735 bytes --]

Seems I misunderstood the usage of SetPosition, thanks for pointing out.  So we can just drop this commit
and keep everything as is, because this check is already present in Ext4Read.

Savva Mitrofanov

> On 10 Dec 2022, at 04:12, Pedro Falcato <pedro.falcato@gmail.com> wrote:
> 
> On Fri, Dec 9, 2022 at 4:11 PM Savva Mitrofanov <savvamtr@gmail.com <mailto:savvamtr@gmail.com>> wrote:
> Missing such comparison leads to infinite loop states, for example code
> which trying to read entire file can easily get out of bound of
> file size by passing position value which exceeds file size without this
> check. So we need to add there missing comparison between the desired
> position to be set and file size
> 
> +  FileSize = EXT4_INODE_SIZE (File->Inode);
> +
>    // -1 (0xffffff.......) seeks to the end of the file
>    if (Position == (UINT64)-1) {
> -    Position = EXT4_INODE_SIZE (File->Inode);
> +    Position = FileSize;
> +  } else if (Position > FileSize) {
> +    DEBUG ((DEBUG_FS, "[ext4] Ext4SetPosition Cannot seek to #%Lx of %Lx\n", Position, FileSize));
> +    return EFI_UNSUPPORTED;
>    }
> 
>    File->Position = Position;
> 
> On further inspection, this case is covered in the UEFI spec.
> 
> https://uefi.org/specs/UEFI/2.10/13_Protocols_Media_Access.html#efi-file-protocol-read <https://uefi.org/specs/UEFI/2.10/13_Protocols_Media_Access.html#efi-file-protocol-read> says:
> 
> > EFI_DEVICE_ERROR     On entry, the current file position is beyond the end of the file.
> 
> while the standard does not say SetPosition() can error out for bad seeks.
> 
> So I think we should allow this in SetPosition() and error out in Read(). Does this look good to you?
>  
> Pedro


[-- Attachment #2: Type: text/html, Size: 3220 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements
  2022-12-09 22:28 ` [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Pedro Falcato
@ 2022-12-12 14:40   ` Savva Mitrofanov
  0 siblings, 0 replies; 18+ messages in thread
From: Savva Mitrofanov @ 2022-12-12 14:40 UTC (permalink / raw)
  To: Pedro Falcato
  Cc: devel, mhaeuser,
	Виталий Юрьевич Чепцов

[-- Attachment #1: Type: text/plain, Size: 2244 bytes --]

Hi! 

Thanks for your review, I did changes in my branch of edk2-platforms and will send corrected patchset soon.

Best regards,
Savva Mitrofanov

> On 10 Dec 2022, at 04:28, Pedro Falcato <pedro.falcato@gmail.com> wrote:
> 
> On Fri, Dec 9, 2022 at 4:11 PM Savva Mitrofanov <savvamtr@gmail.com <mailto:savvamtr@gmail.com>> wrote:
> Hi all,
> 
> This patchset fixes several code problems found by fuzzing Ext4Dxe like
> buffer and integer overflows, memory leaks, logic bugs and so on.
> 
> REF: https://github.com/savvamitrofanov/edk2-platforms/tree/master <https://github.com/savvamitrofanov/edk2-platforms/tree/master>
> 
> Cc: Marvin Häuser <mhaeuser@posteo.de <mailto:mhaeuser@posteo.de>>
> Cc: Pedro Falcato <pedro.falcato@gmail.com <mailto:pedro.falcato@gmail.com>>
> Cc: Vitaly Cheptsov <vit9696@protonmail.com <mailto:vit9696@protonmail.com>>
> 
> Savva Mitrofanov (12):
>   Ext4Pkg: Fix memory leak in Ext4RetrieveDirent
>   Ext4Pkg: Move EXT4_NAME_MAX definition to Ext4Disk.h
>   Ext4Pkg: Fix global buffer overflow in Ext4ReadDir
>   Ext4Pkg: Fix incorrect checksum metadata feature check
>   Ext4Pkg: Fix division by zero by adding check for s_inodes_per_group
>   Ext4Pkg: Add comparison between Position and FileSize in
>     Ext4SetPosition
>   Ext4Pkg: Add inode number validity check
>   Ext4Pkg: Fix shift out of bounds in Ext4OpenSuperblock
>   Ext4Pkg: Correct integer overflow check on multiplication in DiskUtil
>   Ext4Pkg: Check that source file is directory in Ext4OpenInternal
>   Ext4Pkg: Check VolumeName allocation correctness in Ext4GetVolumeName
>   Ext4Pkg: Add missing exit Status in Ext4OpenDirent
> 
> Hi!
> 
> Thanks for the patches (and the fuzzing!). They all mostly lgtm, just some small nits. Please fix them so I can test and merge.
> 
> Also, could you add a Fixes tag to each patch (like in the LKML and elsewhere in OVMF) so we can more easily track what each patch fixes? Using something simple like the oldest git blame of what you're fixing should be enough in this case, no need for git bisect. I just want to establish a good, clean track record here for me and for downstream users to better know what they need to pick up!
> 
> Thanks,
> Pedro


[-- Attachment #2: Type: text/html, Size: 3841 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2022-12-12 14:40 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-09 16:10 [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Savva Mitrofanov
2022-12-09 16:10 ` [edk2-platforms][PATCH v1 01/12] Ext4Pkg: Fix memory leak in Ext4RetrieveDirent Savva Mitrofanov
2022-12-09 16:10 ` [edk2-platforms][PATCH v1 02/12] Ext4Pkg: Move EXT4_NAME_MAX definition to Ext4Disk.h Savva Mitrofanov
2022-12-09 16:10 ` [edk2-platforms][PATCH v1 03/12] Ext4Pkg: Fix global buffer overflow in Ext4ReadDir Savva Mitrofanov
2022-12-09 16:10 ` [edk2-platforms][PATCH v1 04/12] Ext4Pkg: Fix incorrect checksum metadata feature check Savva Mitrofanov
2022-12-09 16:10 ` [edk2-platforms][PATCH v1 05/12] Ext4Pkg: Fix division by zero by adding check for s_inodes_per_group Savva Mitrofanov
2022-12-09 16:10 ` [edk2-platforms][PATCH v1 06/12] Ext4Pkg: Add comparison between Position and FileSize in Ext4SetPosition Savva Mitrofanov
2022-12-09 22:12   ` Pedro Falcato
2022-12-12 11:44     ` Savva Mitrofanov
2022-12-09 16:10 ` [edk2-platforms][PATCH v1 07/12] Ext4Pkg: Add inode number validity check Savva Mitrofanov
2022-12-09 16:11 ` [edk2-platforms][PATCH v1 08/12] Ext4Pkg: Fix shift out of bounds in Ext4OpenSuperblock Savva Mitrofanov
2022-12-09 16:11 ` [edk2-platforms][PATCH v1 09/12] Ext4Pkg: Correct integer overflow check on multiplication in DiskUtil Savva Mitrofanov
2022-12-09 22:16   ` Pedro Falcato
2022-12-09 16:11 ` [edk2-platforms][PATCH v1 10/12] Ext4Pkg: Check that source file is directory in Ext4OpenInternal Savva Mitrofanov
2022-12-09 16:11 ` [edk2-platforms][PATCH v1 11/12] Ext4Pkg: Check VolumeName allocation correctness in Ext4GetVolumeName Savva Mitrofanov
2022-12-09 16:11 ` [edk2-platforms][PATCH v1 12/12] Ext4Pkg: Add missing exit Status in Ext4OpenDirent Savva Mitrofanov
2022-12-09 22:28 ` [edk2-platforms][PATCH v1 00/12] Ext4Pkg: Code correctness and security improvements Pedro Falcato
2022-12-12 14:40   ` Savva Mitrofanov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox