]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: Introduce file_size and use it when we're working with file_offset
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 4 Oct 2024 10:40:32 +0000 (12:40 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 9 Oct 2024 18:36:57 +0000 (20:36 +0200)
When we're reading a section from disk, use file_size to use the
size on disk instead of the size in memory.

src/boot/efi/boot.c
src/boot/efi/pe.c
src/boot/efi/pe.h

index 13a154d0ce157912829548ab6b1ab4182064cc65..a362f7a93f2cacb94f9338b9b47dfefa7e69a8d0 100644 (file)
@@ -1928,8 +1928,8 @@ static bool is_sd_boot(EFI_FILE *root_dir, const char16_t *loader_path) {
         if (vector.memory_size != sizeof(SD_MAGIC))
                 return false;
 
-        err = file_handle_read(handle, vector.file_offset, vector.memory_size, &content, &read);
-        if (err != EFI_SUCCESS || vector.memory_size != read)
+        err = file_handle_read(handle, vector.file_offset, vector.file_size, &content, &read);
+        if (err != EFI_SUCCESS || vector.file_size != read)
                 return false;
 
         return memcmp(content, SD_MAGIC, sizeof(SD_MAGIC)) == 0;
@@ -2210,7 +2210,7 @@ static void boot_entry_add_type2(
                 err = file_handle_read(
                                 handle,
                                 sections[SECTION_OSREL].file_offset,
-                                sections[SECTION_OSREL].memory_size,
+                                sections[SECTION_OSREL].file_size,
                                 &content,
                                 /* ret_size= */ NULL);
                 if (err != EFI_SUCCESS)
@@ -2281,7 +2281,7 @@ static void boot_entry_add_type2(
                         err = file_handle_read(
                                         handle,
                                         sections[SECTION_PROFILE].file_offset,
-                                        sections[SECTION_PROFILE].memory_size,
+                                        sections[SECTION_PROFILE].file_size,
                                         &content,
                                         /* ret_size= */ NULL);
                         if (err != EFI_SUCCESS)
@@ -2348,7 +2348,7 @@ static void boot_entry_add_type2(
                 err = file_handle_read(
                                 handle,
                                 sections[SECTION_CMDLINE].file_offset,
-                                sections[SECTION_CMDLINE].memory_size,
+                                sections[SECTION_CMDLINE].file_size,
                                 &content,
                                 &cmdline_len);
                 if (err == EFI_SUCCESS) {
index 41917b1f4e2fa1b2bee4cca74dbdab8748972372..26dfcd4291fd5fd46c5189fcb8fb4992d80e492b 100644 (file)
@@ -186,13 +186,13 @@ static void pe_locate_sections(
                         /* Overflow check: ignore sections that are impossibly large, relative to the file
                          * address for the section. */
                         size_t size_max = SIZE_MAX - j->PointerToRawData;
-                        if ((size_t) j->VirtualSize > size_max)
+                        if ((size_t) j->SizeOfRawData > size_max)
                                 continue;
 
                         /* Overflow check: ignore sections that are impossibly large, given the virtual
                          * address for the section */
                         size_max = SIZE_MAX - j->VirtualAddress;
-                        if (j->VirtualSize > size_max)
+                        if ((size_t) j->VirtualSize > size_max)
                                 continue;
 
                         /* 2nd overflow check: ignore sections that are impossibly large also taking the
@@ -209,8 +209,14 @@ static void pe_locate_sections(
                         /* At this time, the sizes and offsets have been validated. Store them away */
                         sections[i] = (PeSectionVector) {
                                 .memory_size = j->VirtualSize,
-                                .file_offset = j->PointerToRawData,
                                 .memory_offset = j->VirtualAddress,
+                                /* VirtualSize can be bigger than SizeOfRawData when the section requires
+                                 * uninitialized data. It can also be smaller than SizeOfRawData when there's
+                                 * no need for uninitialized data as SizeOfRawData is aligned to
+                                 * FileAlignment and VirtualSize isn't. The actual data that's read from disk
+                                 * is the minimum of these two fields. */
+                                .file_size = MIN(j->SizeOfRawData, j->VirtualSize),
+                                .file_offset = j->PointerToRawData,
                         };
 
                         /* First matching section wins, ignore the rest */
index 78c2f7ee98aa64a15929ea2a743d461ab4b2b6ec..56312b15b3b5c1a1c0d08174d417b3215323056b 100644 (file)
@@ -22,6 +22,7 @@ typedef struct PeSectionHeader {
 typedef struct PeSectionVector {
         size_t memory_size;     /* Size of the section in memory (corresponds to VirtualSize field) */
         size_t memory_offset;   /* Offset in memory, relative to base address */
+        uint64_t file_size;     /* Amount of bytes of the section read from disk (possibly aligned to FileAlignment in case VirtualSize > SizeOfRawData). */
         uint64_t file_offset;   /* Offset on disk, relative to beginning of file */
 } PeSectionVector;