]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pe: be more careful when loading PE section list into memory
authorLennart Poettering <lennart@poettering.net>
Mon, 24 Jun 2024 13:25:07 +0000 (15:25 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 26 Jun 2024 15:09:44 +0000 (17:09 +0200)
Let's put a limit on how much memory we'll allocate for the section. And
let's add a safety overflow check.

(This is more a theoretic than a real problem, since on all PE archs
NumberOfSections is 16bit only.)

src/boot/efi/pe.c

index 829266b7f599dcfb605926938bab5d97298be636..8c5e5f732d5b82bc6c4208e379a95f5a30b9669a 100644 (file)
@@ -119,6 +119,8 @@ typedef struct PeSectionHeader {
         uint32_t Characteristics;
 } _packed_ PeSectionHeader;
 
+#define SECTION_TABLE_BYTES_MAX (16U * 1024U * 1024U)
+
 static bool verify_dos(const DosFileHeader *dos) {
         assert(dos);
         return memcmp(dos->Magic, DOS_FILE_MAGIC, STRLEN(DOS_FILE_MAGIC)) == 0;
@@ -309,7 +311,13 @@ EFI_STATUS pe_file_locate_sections(
         if (len != sizeof(pe) || !verify_pe(&pe, /* allow_compatibility= */ false))
                 return EFI_LOAD_ERROR;
 
-        section_table_len = pe.FileHeader.NumberOfSections * sizeof(PeSectionHeader);
+        DISABLE_WARNING_TYPE_LIMITS;
+        if ((size_t) pe.FileHeader.NumberOfSections > SIZE_MAX / sizeof(PeSectionHeader))
+                return EFI_OUT_OF_RESOURCES;
+        REENABLE_WARNING;
+        section_table_len = (size_t) pe.FileHeader.NumberOfSections * sizeof(PeSectionHeader);
+        if (section_table_len > SECTION_TABLE_BYTES_MAX)
+                return EFI_OUT_OF_RESOURCES;
         section_table = xmalloc(section_table_len);
         if (!section_table)
                 return EFI_OUT_OF_RESOURCES;