:: commit 87cd7211af6f7e2dfe8d823f37ff70d197f65aeb

Mintsuki <mintsuki@protonmail.com> — 2026-02-07 08:18

parents: 8fa67f768a

protos/multiboot2: Fix SMBIOS tag and module alignment budget, validate header_length

diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c
index 6dbb59d0..63a551ea 100644
--- a/common/protos/multiboot2.c
+++ b/common/protos/multiboot2.c
@@ -118,6 +118,11 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
         panic(true, "multiboot2: Header checksum is invalid");
     }
 
+    size_t header_offset_in_file = (uintptr_t)header - (uintptr_t)kernel;
+    if (header->header_length > kernel_file_size - header_offset_in_file) {
+        panic(true, "multiboot2: Header length exceeds kernel file size");
+    }
+
     struct multiboot_header_tag_address *addresstag = NULL;
     struct multiboot_header_tag_framebuffer *fbtag = NULL;
 
@@ -424,7 +429,7 @@ reloc_fail:
 
         char *module_cmdline = conf_tuple.value2;
         if (!module_cmdline) module_cmdline = "";
-        modules_size += sizeof(struct multiboot_tag_module) + strlen(module_cmdline) + 1;
+        modules_size += ALIGN_UP(sizeof(struct multiboot_tag_module) + strlen(module_cmdline) + 1, MULTIBOOT_TAG_ALIGN);
     }
 
     struct smbios_entry_point_32* smbios_entry_32 = NULL;
@@ -435,9 +440,9 @@ reloc_fail:
     uint32_t smbios_tag_size = 0;
 
     if (smbios_entry_32 != NULL)
-        smbios_tag_size += sizeof(struct multiboot_tag_smbios) + smbios_entry_32->length;
+        smbios_tag_size += ALIGN_UP(sizeof(struct multiboot_tag_smbios) + smbios_entry_32->length, MULTIBOOT_TAG_ALIGN);
     if (smbios_entry_64 != NULL)
-        smbios_tag_size += sizeof(struct multiboot_tag_smbios) + smbios_entry_64->length;
+        smbios_tag_size += ALIGN_UP(sizeof(struct multiboot_tag_smbios) + smbios_entry_64->length, MULTIBOOT_TAG_ALIGN);
 
     size_t mb2_info_size = get_multiboot2_info_size(
         cmdline,
tab: 248 wrap: offon