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,
