:: commit afad8d11ea5c5b60d67284db1fb4595b9516955a

Mintsuki <mintsuki@protonmail.com> — 2026-01-13 04:21

parents: 2b19abd0ce

multiboot1: Add bounds validation for address tag loading

diff --git a/common/protos/multiboot1.c b/common/protos/multiboot1.c
index b31fe9a2..78fa207a 100644
--- a/common/protos/multiboot1.c
+++ b/common/protos/multiboot1.c
@@ -110,11 +110,20 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
         if (header.load_addr > header.header_addr)
             panic(true, "multiboot1: Illegal load address");
 
+        size_t addr_diff = header.header_addr - header.load_addr;
+        if (addr_diff > header_offset)
+            panic(true, "multiboot1: Address tag offset underflow");
+
+        size_t load_src = header_offset - addr_diff;
+
         size_t load_size;
-        if (header.load_end_addr)
+        if (header.load_end_addr) {
             load_size = header.load_end_addr - header.load_addr;
-        else
-            load_size = kernel_file_size;
+        } else {
+            if (load_src > kernel_file_size)
+                panic(true, "multiboot1: Load source exceeds kernel file size");
+            load_size = kernel_file_size - load_src;
+        }
 
         uint32_t bss_size = 0;
         if (header.bss_end_addr) {
@@ -129,8 +138,7 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
 
         void *elsewhere = ext_mem_alloc(full_size);
 
-        memcpy(elsewhere, kernel + (header_offset
-                - (header.header_addr - header.load_addr)), load_size);
+        memcpy(elsewhere, kernel + load_src, load_size);
 
         entry_point = header.entry_addr;
 
tab: 248 wrap: offon