summaryrefslogtreecommitdiffstats
path: root/src/boot
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-10-09 22:26:14 +0200
committerGitHub <noreply@github.com>2024-10-09 22:26:14 +0200
commita0295505070df09ef891dfdb32aae1756b0361bf (patch)
treef08e6fcb331bfb532814a5cf54e9d120a5dc1683 /src/boot
parentstub: reindent lines (diff)
parentmkosi: Fix sections for settings (diff)
downloadsystemd-a0295505070df09ef891dfdb32aae1756b0361bf.tar.xz
systemd-a0295505070df09ef891dfdb32aae1756b0361bf.zip
Merge pull request #34687 from DaanDeMeyer/mkosi
Various fixes
Diffstat (limited to 'src/boot')
-rw-r--r--src/boot/efi/boot.c12
-rw-r--r--src/boot/efi/pe.c18
-rw-r--r--src/boot/efi/pe.h5
-rw-r--r--src/boot/efi/stub.c32
4 files changed, 37 insertions, 30 deletions
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index 213c012e3f..a362f7a93f 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -1925,11 +1925,11 @@ static bool is_sd_boot(EFI_FILE *root_dir, const char16_t *loader_path) {
/* profile= */ UINT_MAX,
/* validate_base= */ 0,
&vector);
- if (vector.size != sizeof(SD_MAGIC))
+ if (vector.memory_size != sizeof(SD_MAGIC))
return false;
- err = file_handle_read(handle, vector.file_offset, vector.size, &content, &read);
- if (err != EFI_SUCCESS || vector.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].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].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].size,
+ sections[SECTION_CMDLINE].file_size,
&content,
&cmdline_len);
if (err == EFI_SUCCESS) {
diff --git a/src/boot/efi/pe.c b/src/boot/efi/pe.c
index 2f9b058eb6..26dfcd4291 100644
--- a/src/boot/efi/pe.c
+++ b/src/boot/efi/pe.c
@@ -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
@@ -208,9 +208,15 @@ static void pe_locate_sections(
/* At this time, the sizes and offsets have been validated. Store them away */
sections[i] = (PeSectionVector) {
- .size = j->VirtualSize,
- .file_offset = j->PointerToRawData,
+ .memory_size = j->VirtualSize,
.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 */
@@ -235,7 +241,7 @@ static uint32_t get_compatibility_entry_address(const DosFileHeader *dos, const
PTR_TO_SIZE(dos),
&vector);
- if (vector.size == 0) /* not found */
+ if (vector.memory_size == 0) /* not found */
return 0;
typedef struct {
@@ -245,7 +251,7 @@ static uint32_t get_compatibility_entry_address(const DosFileHeader *dos, const
uint32_t entry_point;
} _packed_ LinuxPeCompat1;
- size_t addr = vector.memory_offset, size = vector.size;
+ size_t addr = vector.memory_offset, size = vector.memory_size;
while (size >= sizeof(LinuxPeCompat1) && addr % alignof(LinuxPeCompat1) == 0) {
const LinuxPeCompat1 *compat = (const LinuxPeCompat1 *) ((const uint8_t *) dos + addr);
diff --git a/src/boot/efi/pe.h b/src/boot/efi/pe.h
index b9838579cf..56312b15b3 100644
--- a/src/boot/efi/pe.h
+++ b/src/boot/efi/pe.h
@@ -20,13 +20,14 @@ typedef struct PeSectionHeader {
/* This is a subset of the full PE section header structure, with validated values, and without
* the noise. */
typedef struct PeSectionVector {
- size_t size;
+ 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;
static inline bool PE_SECTION_VECTOR_IS_SET(const PeSectionVector *v) {
- return v && v->size != 0;
+ return v && v->memory_size != 0;
}
EFI_STATUS pe_section_table_from_base(
diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
index d3cc809efb..4df993c5d0 100644
--- a/src/boot/efi/stub.c
+++ b/src/boot/efi/stub.c
@@ -58,7 +58,7 @@ static char16_t* pe_section_to_str16(
if (!PE_SECTION_VECTOR_IS_SET(section))
return NULL;
- return xstrn8_to_16((const char *) loaded_image->ImageBase + section->memory_offset, section->size);
+ return xstrn8_to_16((const char *) loaded_image->ImageBase + section->memory_offset, section->memory_size);
}
static char *pe_section_to_str8(
@@ -71,7 +71,7 @@ static char *pe_section_to_str8(
if (!PE_SECTION_VECTOR_IS_SET(section))
return NULL;
- return xstrndup8((const char *)loaded_image->ImageBase + section->memory_offset, section->size);
+ return xstrndup8((const char *)loaded_image->ImageBase + section->memory_offset, section->memory_size);
}
static void combine_measured_flag(int *value, int measured) {
@@ -634,7 +634,7 @@ static EFI_STATUS load_addons(
if (uname && PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_UNAME) &&
!strneq8(uname,
(const char *)loaded_addon->ImageBase + sections[UNIFIED_SECTION_UNAME].memory_offset,
- sections[UNIFIED_SECTION_UNAME].size)) {
+ sections[UNIFIED_SECTION_UNAME].memory_size)) {
log_error(".uname mismatch between %ls and UKI, ignoring", items[i]);
continue;
}
@@ -653,8 +653,8 @@ static EFI_STATUS load_addons(
(*devicetree_addons)[(*n_devicetree_addons)++] = (NamedAddon) {
.blob = {
- .iov_base = xmemdup((const uint8_t*) loaded_addon->ImageBase + sections[UNIFIED_SECTION_DTB].memory_offset, sections[UNIFIED_SECTION_DTB].size),
- .iov_len = sections[UNIFIED_SECTION_DTB].size,
+ .iov_base = xmemdup((const uint8_t*) loaded_addon->ImageBase + sections[UNIFIED_SECTION_DTB].memory_offset, sections[UNIFIED_SECTION_DTB].memory_size),
+ .iov_len = sections[UNIFIED_SECTION_DTB].memory_size,
},
.filename = xstrdup16(items[i]),
};
@@ -666,8 +666,8 @@ static EFI_STATUS load_addons(
(*n_initrd_addons + 1) * sizeof(NamedAddon));
(*initrd_addons)[(*n_initrd_addons)++] = (NamedAddon) {
.blob = {
- .iov_base = xmemdup((const uint8_t*) loaded_addon->ImageBase + sections[UNIFIED_SECTION_INITRD].memory_offset, sections[UNIFIED_SECTION_INITRD].size),
- .iov_len = sections[UNIFIED_SECTION_INITRD].size,
+ .iov_base = xmemdup((const uint8_t*) loaded_addon->ImageBase + sections[UNIFIED_SECTION_INITRD].memory_offset, sections[UNIFIED_SECTION_INITRD].memory_size),
+ .iov_len = sections[UNIFIED_SECTION_INITRD].memory_size,
},
.filename = xstrdup16(items[i]),
};
@@ -679,8 +679,8 @@ static EFI_STATUS load_addons(
(*n_ucode_addons + 1) * sizeof(NamedAddon));
(*ucode_addons)[(*n_ucode_addons)++] = (NamedAddon) {
.blob = {
- .iov_base = xmemdup((const uint8_t*) loaded_addon->ImageBase + sections[UNIFIED_SECTION_UCODE].memory_offset, sections[UNIFIED_SECTION_UCODE].size),
- .iov_len = sections[UNIFIED_SECTION_UCODE].size,
+ .iov_base = xmemdup((const uint8_t*) loaded_addon->ImageBase + sections[UNIFIED_SECTION_UCODE].memory_offset, sections[UNIFIED_SECTION_UCODE].memory_size),
+ .iov_len = sections[UNIFIED_SECTION_UCODE].memory_size,
},
.filename = xstrdup16(items[i]),
};
@@ -748,7 +748,7 @@ static void measure_sections(
(void) tpm_log_ipl_event_ascii(
TPM2_PCR_KERNEL_BOOT,
POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + sections[section].memory_offset,
- sections[section].size,
+ sections[section].memory_size,
unified_sections[section],
&m);
combine_measured_flag(sections_measured, m);
@@ -905,7 +905,7 @@ static void generate_embedded_initrds(
(void) pack_cpio_literal(
(const uint8_t*) loaded_image->ImageBase + sections[t->section].memory_offset,
- sections[t->section].size,
+ sections[t->section].memory_size,
".extra",
t->filename,
/* dir_mode= */ 0555,
@@ -929,12 +929,12 @@ static void lookup_embedded_initrds(
if (PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_INITRD))
initrds[INITRD_BASE] = IOVEC_MAKE(
(const uint8_t*) loaded_image->ImageBase + sections[UNIFIED_SECTION_INITRD].memory_offset,
- sections[UNIFIED_SECTION_INITRD].size);
+ sections[UNIFIED_SECTION_INITRD].memory_size);
if (PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_UCODE))
initrds[INITRD_UCODE] = IOVEC_MAKE(
(const uint8_t*) loaded_image->ImageBase + sections[UNIFIED_SECTION_UCODE].memory_offset,
- sections[UNIFIED_SECTION_UCODE].size);
+ sections[UNIFIED_SECTION_UCODE].memory_size);
}
static void export_pcr_variables(
@@ -973,7 +973,7 @@ static void install_embedded_devicetree(
err = devicetree_install_from_memory(
dt_state,
(const uint8_t*) loaded_image->ImageBase + sections[UNIFIED_SECTION_DTB].memory_offset,
- sections[UNIFIED_SECTION_DTB].size);
+ sections[UNIFIED_SECTION_DTB].memory_size);
if (err != EFI_SUCCESS)
log_error_status(err, "Error loading embedded devicetree, ignoring: %m");
}
@@ -1047,7 +1047,7 @@ static void display_splash(
if (!PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_SPLASH))
return;
- graphics_splash((const uint8_t*) loaded_image->ImageBase + sections[UNIFIED_SECTION_SPLASH].memory_offset, sections[UNIFIED_SECTION_SPLASH].size);
+ graphics_splash((const uint8_t*) loaded_image->ImageBase + sections[UNIFIED_SECTION_SPLASH].memory_offset, sections[UNIFIED_SECTION_SPLASH].memory_size);
}
static EFI_STATUS find_sections(
@@ -1250,7 +1250,7 @@ static EFI_STATUS run(EFI_HANDLE image) {
struct iovec kernel = IOVEC_MAKE(
(const uint8_t*) loaded_image->ImageBase + sections[UNIFIED_SECTION_LINUX].memory_offset,
- sections[UNIFIED_SECTION_LINUX].size);
+ sections[UNIFIED_SECTION_LINUX].memory_size);
err = linux_exec(image, cmdline, &kernel, &final_initrd);
graphics_mode(false);