:: commit eb071a0121fc878e63ba9b0ff037c75a085c17b2

Mintsuki <mintsuki@protonmail.com> — 2026-03-31 16:05

parents: d7f0160ddc

misc: Add overflow checking to ALIGN_UP and DIV_ROUNDUP macros

diff --git a/common/entry.s3.c b/common/entry.s3.c
index 520232f0..7e78d5e0 100644
--- a/common/entry.s3.c
+++ b/common/entry.s3.c
@@ -46,8 +46,8 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 
 #if defined (__x86_64__)
     if ((uintptr_t)__slide >= 0x100000000) {
-        size_t image_size = ALIGN_UP((uintptr_t)__image_end - (uintptr_t)__image_base, 4096);
-        size_t image_size_pages = ALIGN_UP((size_t)image_size, 4096) / 4096;
+        size_t image_size = ALIGN_UP((uintptr_t)__image_end - (uintptr_t)__image_base, 4096, panic(false, "Alignment overflow"));
+        size_t image_size_pages = ALIGN_UP((size_t)image_size, 4096, panic(false, "Alignment overflow")) / 4096;
         size_t new_base;
         for (new_base = 0x1000; new_base + (size_t)image_size < 0x100000000; new_base += 0x1000) {
             EFI_PHYSICAL_ADDRESS _new_base = (EFI_PHYSICAL_ADDRESS)new_base;
diff --git a/common/fs/fat32.s2.c b/common/fs/fat32.s2.c
index 7625a219..cfd664e6 100644
--- a/common/fs/fat32.s2.c
+++ b/common/fs/fat32.s2.c
@@ -209,7 +209,7 @@ bytes_per_sector_valid:;
         return 1;  // Overflow in root_start calculation
     }
     context->root_start = (uint32_t)root_start_64;
-    context->root_size = DIV_ROUNDUP(context->root_entries * sizeof(struct fat32_directory_entry), context->bytes_per_sector);
+    context->root_size = DIV_ROUNDUP(context->root_entries * sizeof(struct fat32_directory_entry), context->bytes_per_sector, return 1);
     switch (context->type) {
         case 12:
         case 16:
@@ -460,7 +460,7 @@ static int fat32_open_in(struct fat32_context* context, struct fat32_directory_e
 
         pmm_free(directory_cluster_chain, dir_chain_len * sizeof(uint32_t));
     } else {
-        dir_chain_len = DIV_ROUNDUP(context->root_entries * sizeof(struct fat32_directory_entry), block_size);
+        dir_chain_len = DIV_ROUNDUP(context->root_entries * sizeof(struct fat32_directory_entry), block_size, return 1);
 
         // Check for overflow
         size_t alloc_size;
diff --git a/common/fs/file.s2.c b/common/fs/file.s2.c
index 3bc064be..5cde4663 100644
--- a/common/fs/file.s2.c
+++ b/common/fs/file.s2.c
@@ -131,7 +131,7 @@ void *freadall_mode(struct file_handle *fd, uint32_t type, bool allow_high_alloc
             fd->fd = newptr;
         } else {
 #endif
-        memmap_alloc_range((uint64_t)(size_t)fd->fd, ALIGN_UP(fd->size, 4096), type, 0, true, false, false);
+        memmap_alloc_range((uint64_t)(size_t)fd->fd, ALIGN_UP(fd->size, 4096, panic(false, "Alignment overflow")), type, 0, true, false, false);
 #if defined (UEFI) && defined (__x86_64__)
         }
 #endif
diff --git a/common/fs/iso9660.s2.c b/common/fs/iso9660.s2.c
index 80b4c3c4..86ae1237 100644
--- a/common/fs/iso9660.s2.c
+++ b/common/fs/iso9660.s2.c
@@ -261,7 +261,7 @@ static struct iso9660_directory_entry *iso9660_next_entry(void *current, void *b
     if (entry->length == 0) {
         // Skip to next sector boundary
         uintptr_t current_addr = (uintptr_t)current;
-        uintptr_t next_sector = ALIGN_UP(current_addr + 1, ISO9660_SECTOR_SIZE);
+        uintptr_t next_sector = ALIGN_UP(current_addr + 1, ISO9660_SECTOR_SIZE, return NULL);
         if (next_sector >= (uintptr_t)buffer_end)
             return NULL;
         entry = (struct iso9660_directory_entry *)next_sector;
@@ -278,7 +278,7 @@ static struct iso9660_directory_entry *iso9660_next_entry(void *current, void *b
 
     // Handle zero-length entries (padding at sector boundaries)
     if (entry->length == 0) {
-        uintptr_t next_sector = ALIGN_UP((uintptr_t)next + 1, ISO9660_SECTOR_SIZE);
+        uintptr_t next_sector = ALIGN_UP((uintptr_t)next + 1, ISO9660_SECTOR_SIZE, return NULL);
         if (next_sector >= (uintptr_t)buffer_end)
             return NULL;
         entry = (struct iso9660_directory_entry *)next_sector;
diff --git a/common/lib/acpi.c b/common/lib/acpi.c
index b012dd1c..52afaf13 100644
--- a/common/lib/acpi.c
+++ b/common/lib/acpi.c
@@ -289,7 +289,7 @@ static void map_single_table(uint64_t addr, uint32_t len) {
     uint32_t length = len != (uint32_t)-1 ? len : *(uint32_t *)(uintptr_t)(addr + 4);
 
     uint64_t aligned_base = ALIGN_DOWN(addr, 4096);
-    uint64_t aligned_top  = ALIGN_UP(addr + length, 4096);
+    uint64_t aligned_top  = ALIGN_UP(addr + length, 4096, panic(false, "acpi: Alignment overflow"));
 
     if (!acpi_padding_is_safe(aligned_base, addr - aligned_base)) {
         aligned_base = addr;
diff --git a/common/lib/elf.c b/common/lib/elf.c
index 1b12f342..d7763c36 100644
--- a/common/lib/elf.c
+++ b/common/lib/elf.c
@@ -801,7 +801,7 @@ static void elf64_get_ranges(uint8_t *elf, uint64_t slide, struct mem_range **_r
 
         uint64_t align = phdr->p_align <= 1 ? 1 : phdr->p_align;
         ranges[r].base = load_addr & ~(align - 1);
-        ranges[r].length = ALIGN_UP(this_top - ranges[r].base, align);
+        ranges[r].length = ALIGN_UP(this_top - ranges[r].base, align, panic(true, "elf: Alignment overflow"));
 
         if (phdr->p_flags & ELF_PF_X) {
             ranges[r].permissions |= MEM_RANGE_X;
@@ -921,9 +921,9 @@ bool elf64_load(uint8_t *elf, size_t file_size, uint64_t *entry_point, uint64_t
 
             if (ranges != NULL) {
                 uint64_t page_rounded_base = ALIGN_DOWN(phdr->p_vaddr, 4096);
-                uint64_t page_rounded_top = ALIGN_UP(phdr_end, 4096);
+                uint64_t page_rounded_top = ALIGN_UP(phdr_end, 4096, panic(true, "elf: PHDR alignment overflow"));
                 uint64_t page_rounded_base_in = ALIGN_DOWN(phdr_in->p_vaddr, 4096);
-                uint64_t page_rounded_top_in = ALIGN_UP(phdr_in_end, 4096);
+                uint64_t page_rounded_top_in = ALIGN_UP(phdr_in_end, 4096, panic(true, "elf: PHDR alignment overflow"));
 
                 if ((page_rounded_base >= page_rounded_base_in
                   && page_rounded_base < page_rounded_top_in)
diff --git a/common/lib/elsewhere.c b/common/lib/elsewhere.c
index 960020af..69c7ae61 100644
--- a/common/lib/elsewhere.c
+++ b/common/lib/elsewhere.c
@@ -28,7 +28,7 @@ bool elsewhere_append(
             }
         }
 
-        *target = ALIGN_UP(top, 4096);
+        *target = ALIGN_UP(top, 4096, return false);
     }
 
     uint64_t max_retries = 0x10000;
@@ -56,7 +56,7 @@ retry:
                 if (!flexible_target) {
                     return false;
                 }
-                *target = ALIGN_UP(top, 4096);
+                *target = ALIGN_UP(top, 4096, return false);
                 goto retry;
             }
         }
diff --git a/common/lib/fb.c b/common/lib/fb.c
index 4c64a81a..51fc49ae 100644
--- a/common/lib/fb.c
+++ b/common/lib/fb.c
@@ -83,7 +83,7 @@ static void fb_flush_x86(volatile void *base, size_t length) {
     }
 
     uintptr_t start = ALIGN_DOWN((uintptr_t)base, clsz);
-    uintptr_t end = ALIGN_UP((uintptr_t)base + length, clsz);
+    uintptr_t end = ALIGN_UP((uintptr_t)base + length, clsz, panic(false, "fb: Alignment overflow"));
     for (uintptr_t ptr = start; ptr < end; ptr += clsz) {
         asm volatile ("clflush (%0)" :: "r"(ptr) : "memory");
     }
@@ -103,7 +103,7 @@ __attribute__((target("arch=+zicbom")))
 static void fb_flush_riscv(volatile void *base, size_t length) {
     const size_t cbom_block_size = 0x40;
     uintptr_t start = ALIGN_DOWN((uintptr_t)base, cbom_block_size);
-    uintptr_t end = ALIGN_UP((uintptr_t)(base + length), cbom_block_size);
+    uintptr_t end = ALIGN_UP((uintptr_t)(base + length), cbom_block_size, panic(false, "fb: Alignment overflow"));
     for (uintptr_t ptr = start; ptr < end; ptr += cbom_block_size) {
         asm volatile("cbo.flush (%0)" :: "r"(ptr) : "memory");
     }
@@ -133,7 +133,7 @@ static void fb_flush_loongarch64(volatile void *base, size_t length) {
     // cacop Hit_Writeback_Inv_LEAF0 = 0x10 (D-cache L1 writeback+invalidate)
     const size_t clsz = 64;
     uintptr_t start = ALIGN_DOWN((uintptr_t)base, clsz);
-    uintptr_t end = ALIGN_UP((uintptr_t)base + length, clsz);
+    uintptr_t end = ALIGN_UP((uintptr_t)base + length, clsz, panic(false, "fb: Alignment overflow"));
     for (uintptr_t ptr = start; ptr < end; ptr += clsz) {
         asm volatile ("cacop 0x10, %0, 0" :: "r"(ptr) : "memory");
     }
diff --git a/common/lib/misc.h b/common/lib/misc.h
index 4f074bc5..f0c59615 100644
--- a/common/lib/misc.h
+++ b/common/lib/misc.h
@@ -81,16 +81,16 @@ uint64_t strtoui(const char *s, const char **end, int base);
     CHECKED_ADD_res; \
 })
 
-#define DIV_ROUNDUP(a, b) ({ \
+#define DIV_ROUNDUP(a, b, onerror) ({ \
     __auto_type DIV_ROUNDUP_a = (a); \
     __auto_type DIV_ROUNDUP_b = (b); \
-    (DIV_ROUNDUP_a + (DIV_ROUNDUP_b - 1)) / DIV_ROUNDUP_b; \
+    CHECKED_ADD(DIV_ROUNDUP_a, DIV_ROUNDUP_b - 1, onerror) / DIV_ROUNDUP_b; \
 })
 
-#define ALIGN_UP(x, a) ({ \
+#define ALIGN_UP(x, a, onerror) ({ \
     __auto_type ALIGN_UP_value = (x); \
     __auto_type ALIGN_UP_align = (a); \
-    ALIGN_UP_value = DIV_ROUNDUP(ALIGN_UP_value, ALIGN_UP_align) * ALIGN_UP_align; \
+    ALIGN_UP_value = DIV_ROUNDUP(ALIGN_UP_value, ALIGN_UP_align, onerror) * ALIGN_UP_align; \
     ALIGN_UP_value; \
 })
 
diff --git a/common/lib/pe.c b/common/lib/pe.c
index 8c727fd8..2f8598b4 100644
--- a/common/lib/pe.c
+++ b/common/lib/pe.c
@@ -465,7 +465,7 @@ again:
         if (!headers_within_section) {
             struct mem_range *range = &ranges[range_index++];
             range->base = *virtual_base;
-            range->length = ALIGN_UP(nt_hdrs->OptionalHeader.SizeOfHeaders, 0x1000);
+            range->length = ALIGN_UP(nt_hdrs->OptionalHeader.SizeOfHeaders, 0x1000, panic(true, "pe: Alignment overflow"));
             range->permissions = MEM_RANGE_R;
         }
 
@@ -476,7 +476,7 @@ again:
 
             struct mem_range *range = &ranges[range_index++];
             range->base = *virtual_base + ALIGN_DOWN(section->VirtualAddress, alignment);
-            range->length = ALIGN_UP(section->VirtualSize + misalign, alignment);
+            range->length = ALIGN_UP(section->VirtualSize + misalign, alignment, panic(true, "pe: Alignment overflow"));
 
             if (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
                 range->permissions |= MEM_RANGE_X;
diff --git a/common/menu.c b/common/menu.c
index 2b251492..5c388bb4 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -239,7 +239,7 @@ refresh:
         size_t x, y;
         print("\n");
         terms[0]->get_cursor_pos(terms[0], &x, &y);
-        set_cursor_pos_helper(terms[0]->cols / 2 - DIV_ROUNDUP(strlen(menu_branding), 2), y);
+        set_cursor_pos_helper(terms[0]->cols / 2 - DIV_ROUNDUP(strlen(menu_branding), 2, panic(false, "Alignment overflow")), y);
         print("\e[3%sm%s\e[0m", menu_branding_colour, menu_branding);
         print("\n\n");
     }
@@ -257,7 +257,7 @@ refresh:
                 // FALLTHRU
             default: {
                 size_t title_length = strlen(title);
-                if (i == (terms[0]->cols / 2) - DIV_ROUNDUP(title_length, 2) - 1 - 1) {
+                if (i == (terms[0]->cols / 2) - DIV_ROUNDUP(title_length, 2, panic(false, "Alignment overflow")) - 1 - 1) {
                     print(serial ? "|%s|" : "┤%s├", title);
                     i += (title_length + 2) - 1;
                 } else {
@@ -1240,7 +1240,7 @@ refresh:
         size_t x, y;
         print("\n");
         terms[0]->get_cursor_pos(terms[0], &x, &y);
-        set_cursor_pos_helper(terms[0]->cols / 2 - DIV_ROUNDUP(strlen(menu_branding), 2), y);
+        set_cursor_pos_helper(terms[0]->cols / 2 - DIV_ROUNDUP(strlen(menu_branding), 2, panic(false, "Alignment overflow")), y);
         print("\e[3%sm%s\e[0m", menu_branding_colour, menu_branding);
         print("\n\n\n\n");
     }
@@ -1266,7 +1266,7 @@ refresh:
 
     if (max_entries != 0) {
         size_t half_cols = terms[0]->cols / 2;
-        size_t half_tree = DIV_ROUNDUP(max_tree_len, 2);
+        size_t half_tree = DIV_ROUNDUP(max_tree_len, 2, panic(false, "Alignment overflow"));
         size_t tree_prefix_len = (half_cols > half_tree + 2) ? (half_cols - half_tree - 2) : 0;
         char *tree_prefix = ext_mem_alloc(tree_prefix_len + 1);
         memset(tree_prefix, ' ', tree_prefix_len);
diff --git a/common/mm/pmm.s2.c b/common/mm/pmm.s2.c
index 693b9637..dba2754d 100644
--- a/common/mm/pmm.s2.c
+++ b/common/mm/pmm.s2.c
@@ -25,7 +25,7 @@ void *conv_mem_alloc(uint64_t count) {
     if (allocations_disallowed)
         panic(false, "Memory allocations disallowed");
 
-    count = ALIGN_UP(count, 4096);
+    count = ALIGN_UP(count, 4096, panic(false, "Alignment overflow"));
 
     for (;;) {
         if (base + count > 0x100000)
@@ -106,7 +106,7 @@ static bool align_entry(uint64_t *base, uint64_t *length) {
 
     uint64_t orig_base = *base;
 
-    *base = ALIGN_UP(*base, PAGE_SIZE);
+    *base = ALIGN_UP(*base, PAGE_SIZE, return false);
 
     *length -= (*base - orig_base);
     *length =  ALIGN_DOWN(*length, PAGE_SIZE);
@@ -297,7 +297,7 @@ void init_memmap(void) {
 
     // Allocate bootloader itself
     memmap_alloc_range(4096,
-        ALIGN_UP((uintptr_t)bss_end, 4096) - 4096, MEMMAP_BOOTLOADER_RECLAIMABLE, 0, true, false, false);
+        ALIGN_UP((uintptr_t)bss_end, 4096, panic(false, "Alignment overflow")) - 4096, MEMMAP_BOOTLOADER_RECLAIMABLE, 0, true, false, false);
 
     pmm_sanitise_entries(memmap, &memmap_entries, false);
 
@@ -438,7 +438,7 @@ void init_memmap(void) {
     untouched_memmap_entries = memmap_entries;
 
     // Allocate bootloader itself
-    size_t image_size = ALIGN_UP((uintptr_t)__image_end - (uintptr_t)__image_base, 4096);
+    size_t image_size = ALIGN_UP((uintptr_t)__image_end - (uintptr_t)__image_base, 4096, panic(false, "Alignment overflow"));
 
     memmap_alloc_range((uintptr_t)__slide, (uintptr_t)image_size,
                        MEMMAP_BOOTLOADER_RECLAIMABLE, 0, true, false, true);
@@ -583,7 +583,7 @@ void pmm_free_size_t(void *ptr, size_t length) {
 }
 
 void pmm_free(void *ptr, uint64_t count) {
-    count = ALIGN_UP(count, 4096);
+    count = ALIGN_UP(count, 4096, panic(false, "Alignment overflow"));
     if (allocations_disallowed)
         panic(false, "Memory allocations disallowed");
     memmap_alloc_range((uintptr_t)ptr, count, MEMMAP_USABLE, 0, false, false, true);
diff --git a/common/protos/chainload.c b/common/protos/chainload.c
index 6dbfc8f2..e23cfee5 100644
--- a/common/protos/chainload.c
+++ b/common/protos/chainload.c
@@ -277,7 +277,7 @@ noreturn void chainload(char *config, char *cmdline) {
     size_t image_size = image->size;
 
     memmap_alloc_range_in(untouched_memmap, &untouched_memmap_entries,
-                          (uintptr_t)ptr, ALIGN_UP(image_size, 4096),
+                          (uintptr_t)ptr, ALIGN_UP(image_size, 4096, panic(true, "chainload: Alignment overflow")),
                           MEMMAP_RESERVED, MEMMAP_USABLE, true, false, true);
 
     EFI_DEVICE_PATH_PROTOCOL *efi_file_path = build_relative_efi_file_path(image);
diff --git a/common/protos/limine.c b/common/protos/limine.c
index 773d2b64..060a235e 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -89,7 +89,7 @@ static uint64_t get_hhdm_span_top(int base_revision) {
             continue;
         }
 
-        uint64_t aligned_top = ALIGN_UP(top, 0x40000000);
+        uint64_t aligned_top = ALIGN_UP(top, 0x40000000, continue);
 
         if (aligned_top > ret) {
             ret = aligned_top;
@@ -134,7 +134,7 @@ static pagemap_t build_identity_map(void) {
         }
 
         uint64_t aligned_base   = ALIGN_DOWN(base, 0x1000);
-        uint64_t aligned_top    = ALIGN_UP(top, 0x1000);
+        uint64_t aligned_top    = ALIGN_UP(top, 0x1000, continue);
         uint64_t aligned_length = aligned_top - aligned_base;
 
         map_pages(pagemap, aligned_base, aligned_base, VMM_FLAG_WRITE, aligned_length);
@@ -237,7 +237,7 @@ static pagemap_t build_pagemap(int base_revision,
         }
 
         aligned_base = ALIGN_DOWN(base, 0x1000);
-        aligned_top  = ALIGN_UP(top, 0x1000);
+        aligned_top  = ALIGN_UP(top, 0x1000, continue);
 
         if (aligned_base == pending_top && pending_top != 0) {
             pending_top = aligned_top;
@@ -275,7 +275,7 @@ flush:
         uint64_t top    = CHECKED_ADD(base, length, continue);
 
         uint64_t aligned_base   = ALIGN_DOWN(base, 0x1000);
-        uint64_t aligned_top    = ALIGN_UP(top, 0x1000);
+        uint64_t aligned_top    = ALIGN_UP(top, 0x1000, continue);
         uint64_t aligned_length = aligned_top - aligned_base;
 
         if (base_revision == 0) {
@@ -1346,7 +1346,7 @@ FEAT_END
         uint64_t fb_base = memmap[i].base;
         uint64_t fb_top = CHECKED_ADD(fb_base, memmap[i].length, continue);
         uint64_t fb_aligned_base = ALIGN_DOWN(fb_base, 4096);
-        uint64_t fb_aligned_top = ALIGN_UP(fb_top, 4096);
+        uint64_t fb_aligned_top = ALIGN_UP(fb_top, 4096, continue);
 
         // No overshoot means no possible overlap.
         if (fb_aligned_base == fb_base && fb_aligned_top == fb_top) {
diff --git a/common/protos/linux_risc.c b/common/protos/linux_risc.c
index c53f1dd7..c0150126 100644
--- a/common/protos/linux_risc.c
+++ b/common/protos/linux_risc.c
@@ -126,7 +126,7 @@ static void load_module(struct boot_param *p, char *config) {
 
         p->module_size = module_file->size;
         p->module_base = ext_mem_alloc_type_aligned(
-                        ALIGN_UP(p->module_size, 4096),
+                        ALIGN_UP(p->module_size, 4096, panic(true, "linux: Alignment overflow")),
                         MEMMAP_KERNEL_AND_MODULES, 4096);
 
         fread(module_file, p->module_base, 0, p->module_size);
@@ -482,7 +482,7 @@ noreturn void linux_load(char *config, char *cmdline) {
 #endif
 
     p.kernel_base = ext_mem_alloc_type_aligned(
-                ALIGN_UP(text_offset + kernel_alloc_size, 4096),
+                ALIGN_UP(text_offset + kernel_alloc_size, 4096, panic(true, "linux: Alignment overflow")),
                 MEMMAP_KERNEL_AND_MODULES, 2 * 1024 * 1024);
     p.kernel_base += text_offset;
     fread(kernel_file, p.kernel_base, 0, p.kernel_size);
diff --git a/common/protos/linux_x86.c b/common/protos/linux_x86.c
index 72e0a9d1..86655b0b 100644
--- a/common/protos/linux_x86.c
+++ b/common/protos/linux_x86.c
@@ -395,10 +395,10 @@ noreturn void linux_load(char *config, char *cmdline) {
     if (setup_header->version >= 0x205 && setup_header->kernel_alignment > kernel_align) {
         kernel_align = setup_header->kernel_alignment;
     }
-    uintptr_t kernel_load_addr = ALIGN_UP(0x100000, kernel_align);
+    uintptr_t kernel_load_addr = ALIGN_UP(0x100000, kernel_align, panic(true, "linux: Alignment overflow"));
     for (;;) {
         if (memmap_alloc_range(kernel_load_addr,
-                ALIGN_UP(kernel_alloc_size, 4096),
+                ALIGN_UP(kernel_alloc_size, 4096, panic(true, "linux: Alignment overflow")),
                 MEMMAP_BOOTLOADER_RECLAIMABLE, MEMMAP_USABLE, false, false, false))
             break;
 
@@ -479,7 +479,7 @@ noreturn void linux_load(char *config, char *cmdline) {
             panic(true, "linux: Failed to allocate memory for modules");
         }
 
-        if (memmap_alloc_range(modules_mem_base, ALIGN_UP(size_of_all_modules, 0x100000),
+        if (memmap_alloc_range(modules_mem_base, ALIGN_UP(size_of_all_modules, 0x100000, panic(true, "linux: Alignment overflow")),
                                MEMMAP_BOOTLOADER_RECLAIMABLE, MEMMAP_USABLE, false, false, false))
             break;
 
@@ -580,7 +580,7 @@ set_textmode:;
 
 #if defined (BIOS)
         screen_info->orig_video_isVGA = VIDEO_TYPE_VLFB;
-        screen_info->lfb_size = DIV_ROUNDUP(screen_info->lfb_size, 65536);
+        screen_info->lfb_size = DIV_ROUNDUP(screen_info->lfb_size, 65536, panic(true, "linux: Alignment overflow"));
 #elif defined (UEFI)
         screen_info->orig_video_isVGA = VIDEO_TYPE_EFI;
 #endif
diff --git a/common/protos/multiboot1.c b/common/protos/multiboot1.c
index 5e95e292..5beff944 100644
--- a/common/protos/multiboot1.c
+++ b/common/protos/multiboot1.c
@@ -35,18 +35,20 @@ static size_t get_multiboot1_info_size(
     size_t modules_count, size_t modules_cmdlines_size,
     uint32_t section_entry_size, uint32_t section_num
 ) {
-    return ALIGN_UP(sizeof(struct multiboot1_info), 16) +                   // base structure
-           ALIGN_UP(strlen(cmdline) + 1, 16) +                              // cmdline
-           ALIGN_UP(sizeof(LIMINE_BRAND), 16) +                             // bootloader brand
-           ALIGN_UP(section_entry_size * section_num, 16) +                 // ELF info
-           ALIGN_UP(sizeof(struct multiboot1_module) * modules_count, 16) + // modules count
-           ALIGN_UP(modules_cmdlines_size, 16) +                            // modules command lines
-           ALIGN_UP(sizeof(struct multiboot1_mmap_entry) * MEMMAP_MAX, 16);        // memory map
+#define OVERFLOW panic(false, "multiboot1: info size overflow")
+    return ALIGN_UP(sizeof(struct multiboot1_info), 16, OVERFLOW) +
+           ALIGN_UP(strlen(cmdline) + 1, 16, OVERFLOW) +
+           ALIGN_UP(sizeof(LIMINE_BRAND), 16, OVERFLOW) +
+           ALIGN_UP(section_entry_size * section_num, 16, OVERFLOW) +
+           ALIGN_UP(sizeof(struct multiboot1_module) * modules_count, 16, OVERFLOW) +
+           ALIGN_UP(modules_cmdlines_size, 16, OVERFLOW) +
+           ALIGN_UP(sizeof(struct multiboot1_mmap_entry) * MEMMAP_MAX, 16, OVERFLOW);
+#undef OVERFLOW
 }
 
 static void *mb1_info_alloc(void **mb1_info_raw, size_t size) {
     void *ret = *mb1_info_raw;
-    *mb1_info_raw += ALIGN_UP(size, 16);
+    *mb1_info_raw += ALIGN_UP(size, 16, panic(false, "multiboot: info alloc overflow"));
     return ret;
 }
 
@@ -188,7 +190,7 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
 
         char *module_cmdline = conf_tuple.value2;
         if (!module_cmdline) module_cmdline = "";
-        modules_cmdlines_size += ALIGN_UP(strlen(module_cmdline) + 1, 16);
+        modules_cmdlines_size += ALIGN_UP(strlen(module_cmdline) + 1, 16, panic(false, "multiboot: info size overflow"));
     }
 
     size_t mb1_info_size = get_multiboot1_info_size(
diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c
index d3fdf6e6..fe020fad 100644
--- a/common/protos/multiboot2.c
+++ b/common/protos/multiboot2.c
@@ -40,34 +40,36 @@ static size_t get_multiboot2_info_size(
     uint32_t section_entry_size, uint32_t section_num,
     uint32_t smbios_tag_size
 ) {
-    return ALIGN_UP(sizeof(struct multiboot2_start_tag), MULTIBOOT_TAG_ALIGN) +                                         // start
-        ALIGN_UP(sizeof(struct multiboot_tag_string) + strlen(cmdline) + 1, MULTIBOOT_TAG_ALIGN) +                      // cmdline
-        ALIGN_UP(sizeof(struct multiboot_tag_string) + sizeof(LIMINE_BRAND), MULTIBOOT_TAG_ALIGN) +                     // bootloader brand
-        ALIGN_UP(sizeof(struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN) +                                       // framebuffer
-        ALIGN_UP(sizeof(struct multiboot_tag_new_acpi) + sizeof(struct rsdp), MULTIBOOT_TAG_ALIGN) +                    // new ACPI info
-        ALIGN_UP(sizeof(struct multiboot_tag_old_acpi) + 20, MULTIBOOT_TAG_ALIGN) +                                     // old ACPI info
-        ALIGN_UP(sizeof(struct multiboot_tag_elf_sections) + section_entry_size * section_num, MULTIBOOT_TAG_ALIGN) +   // ELF info
-        ALIGN_UP(modules_size, MULTIBOOT_TAG_ALIGN) +                                                                   // modules
-        ALIGN_UP(sizeof(struct multiboot_tag_load_base_addr), MULTIBOOT_TAG_ALIGN) +                                    // load base address
-        ALIGN_UP(smbios_tag_size, MULTIBOOT_TAG_ALIGN) +                                                                // SMBIOS
-        ALIGN_UP(sizeof(struct multiboot_tag_basic_meminfo), MULTIBOOT_TAG_ALIGN) +                                     // basic memory info
-        ALIGN_UP(sizeof(struct multiboot_tag_mmap) + sizeof(struct multiboot_mmap_entry) * MEMMAP_MAX, MULTIBOOT_TAG_ALIGN) +  // MMAP
+#define OVERFLOW panic(false, "multiboot2: info size overflow")
+    return ALIGN_UP(sizeof(struct multiboot2_start_tag), MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+        ALIGN_UP(sizeof(struct multiboot_tag_string) + strlen(cmdline) + 1, MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+        ALIGN_UP(sizeof(struct multiboot_tag_string) + sizeof(LIMINE_BRAND), MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+        ALIGN_UP(sizeof(struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+        ALIGN_UP(sizeof(struct multiboot_tag_new_acpi) + sizeof(struct rsdp), MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+        ALIGN_UP(sizeof(struct multiboot_tag_old_acpi) + 20, MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+        ALIGN_UP(sizeof(struct multiboot_tag_elf_sections) + section_entry_size * section_num, MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+        ALIGN_UP(modules_size, MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+        ALIGN_UP(sizeof(struct multiboot_tag_load_base_addr), MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+        ALIGN_UP(smbios_tag_size, MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+        ALIGN_UP(sizeof(struct multiboot_tag_basic_meminfo), MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+        ALIGN_UP(sizeof(struct multiboot_tag_mmap) + sizeof(struct multiboot_mmap_entry) * MEMMAP_MAX, MULTIBOOT_TAG_ALIGN, OVERFLOW) +
         #if defined (UEFI)
-            ALIGN_UP(sizeof(struct multiboot_tag_efi_mmap) + (efi_desc_size * EFI_MEMMAP_MAX), MULTIBOOT_TAG_ALIGN) +          // EFI MMAP
+            ALIGN_UP(sizeof(struct multiboot_tag_efi_mmap) + (efi_desc_size * EFI_MEMMAP_MAX), MULTIBOOT_TAG_ALIGN, OVERFLOW) +
             #if defined (__i386__)
-                ALIGN_UP(sizeof(struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN) +                                     // EFI system table 32
-                ALIGN_UP(sizeof(struct multiboot_tag_efi32_ih), MULTIBOOT_TAG_ALIGN) +                                  // EFI image handle 32
+                ALIGN_UP(sizeof(struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+                ALIGN_UP(sizeof(struct multiboot_tag_efi32_ih), MULTIBOOT_TAG_ALIGN, OVERFLOW) +
             #elif defined (__x86_64__)
-                ALIGN_UP(sizeof(struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN) +                                     // EFI system table 64
-                ALIGN_UP(sizeof(struct multiboot_tag_efi64_ih), MULTIBOOT_TAG_ALIGN) +                                  // EFI image handle 64
+                ALIGN_UP(sizeof(struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+                ALIGN_UP(sizeof(struct multiboot_tag_efi64_ih), MULTIBOOT_TAG_ALIGN, OVERFLOW) +
             #endif
         #endif
-        ALIGN_UP(sizeof(struct multiboot_tag_network) + DHCP_ACK_PACKET_LEN, MULTIBOOT_TAG_ALIGN) +                  // network info
-        ALIGN_UP(sizeof(struct multiboot_tag), MULTIBOOT_TAG_ALIGN);                                                    // end
+        ALIGN_UP(sizeof(struct multiboot_tag_network) + DHCP_ACK_PACKET_LEN, MULTIBOOT_TAG_ALIGN, OVERFLOW) +
+        ALIGN_UP(sizeof(struct multiboot_tag), MULTIBOOT_TAG_ALIGN, OVERFLOW);
+#undef OVERFLOW
 }
 
 #define append_tag(P, TAG) do { \
-    (P) += ALIGN_UP((TAG)->size, MULTIBOOT_TAG_ALIGN); \
+    (P) += ALIGN_UP((TAG)->size, MULTIBOOT_TAG_ALIGN, panic(false, "multiboot2: tag size overflow")); \
 } while (0)
 
 noreturn void multiboot2_load(char *config, char* cmdline) {
@@ -149,7 +151,7 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
     // Iterate through the entries...
     for (struct multiboot_header_tag *tag = (struct multiboot_header_tag*)(header + 1); // header + 1 to skip the header struct.
        tag < (struct multiboot_header_tag *)((uintptr_t)header + header->header_length) && tag->type != MULTIBOOT_HEADER_TAG_END;
-       tag = (struct multiboot_header_tag *)((uintptr_t)tag + ALIGN_UP(tag->size, MULTIBOOT_TAG_ALIGN))) {
+       tag = (struct multiboot_header_tag *)((uintptr_t)tag + ALIGN_UP(tag->size, MULTIBOOT_TAG_ALIGN, break))) {
         if (tag->size == 0) {
             break;
         }
@@ -381,7 +383,7 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
             default:
             case 0: case 1: // No preference / prefer lowest
                 reloc_ascend = true;
-                relocated_base = ALIGN_UP(reloc_tag.min_addr, reloc_tag.align);
+                relocated_base = ALIGN_UP(reloc_tag.min_addr, reloc_tag.align, goto reloc_fail);
                 if (CHECKED_ADD(relocated_base, ranges->length, goto reloc_fail) > reloc_tag.max_addr) {
                     goto reloc_fail;
                 }
@@ -440,7 +442,7 @@ reloc_fail:
 
         char *module_cmdline = conf_tuple.value2;
         if (!module_cmdline) module_cmdline = "";
-        modules_size += ALIGN_UP(sizeof(struct multiboot_tag_module) + strlen(module_cmdline) + 1, MULTIBOOT_TAG_ALIGN);
+        modules_size += ALIGN_UP(sizeof(struct multiboot_tag_module) + strlen(module_cmdline) + 1, MULTIBOOT_TAG_ALIGN, panic(false, "multiboot2: modules size overflow"));
     }
 
     struct smbios_entry_point_32* smbios_entry_32 = NULL;
@@ -451,9 +453,9 @@ reloc_fail:
     uint32_t smbios_tag_size = 0;
 
     if (smbios_entry_32 != NULL)
-        smbios_tag_size += ALIGN_UP(sizeof(struct multiboot_tag_smbios) + smbios_entry_32->length, MULTIBOOT_TAG_ALIGN);
+        smbios_tag_size += ALIGN_UP(sizeof(struct multiboot_tag_smbios) + smbios_entry_32->length, MULTIBOOT_TAG_ALIGN, panic(false, "multiboot2: tag size overflow"));
     if (smbios_entry_64 != NULL)
-        smbios_tag_size += ALIGN_UP(sizeof(struct multiboot_tag_smbios) + smbios_entry_64->length, MULTIBOOT_TAG_ALIGN);
+        smbios_tag_size += ALIGN_UP(sizeof(struct multiboot_tag_smbios) + smbios_entry_64->length, MULTIBOOT_TAG_ALIGN, panic(false, "multiboot2: tag size overflow"));
 
     size_t mb2_info_size = get_multiboot2_info_size(
         cmdline,
tab: 248 wrap: offon