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;
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)
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)
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) {
/* 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
/* 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 */
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;