misc: Use CHECKED_ADD for overflow-checked additions
diff --git a/common/fs/fat32.s2.c b/common/fs/fat32.s2.c
index cfac7417..dc287868 100644
--- a/common/fs/fat32.s2.c
+++ b/common/fs/fat32.s2.c
@@ -213,10 +213,7 @@ bytes_per_sector_valid:;
switch (context->type) {
case 12:
case 16:
- // Check for overflow in data_start_lba calculation
- if (__builtin_add_overflow(context->root_start, context->root_size, &context->data_start_lba)) {
- return 1;
- }
+ context->data_start_lba = CHECKED_ADD(context->root_start, context->root_size, return 1);
break;
case 32:
context->data_start_lba = context->root_start;
@@ -642,9 +639,7 @@ struct file_handle *fat32_open(struct volume *part, const char *path) {
for (unsigned int i = 0; i < SIZEOF_ARRAY(current_part) - 1; i++) {
// Check for overflow before computing path index
unsigned int path_idx;
- if (__builtin_add_overflow(i, current_index, &path_idx)) {
- return NULL; // Path index would overflow
- }
+ path_idx = CHECKED_ADD(i, current_index, return NULL);
if (path[path_idx] == 0) {
memcpy(current_part, path + current_index, i);
@@ -657,12 +652,7 @@ struct file_handle *fat32_open(struct volume *part, const char *path) {
if (path[path_idx] == '/') {
memcpy(current_part, path + current_index, i);
current_part[i] = 0;
- // Check for overflow before updating current_index
- unsigned int new_index;
- if (__builtin_add_overflow(current_index, i + 1, &new_index)) {
- return NULL; // current_index would overflow
- }
- current_index = new_index;
+ current_index = CHECKED_ADD(current_index, i + 1, return NULL);
expect_directory = true;
found_terminator = true;
break;
diff --git a/common/lib/acpi.c b/common/lib/acpi.c
index 32e9c655..b012dd1c 100644
--- a/common/lib/acpi.c
+++ b/common/lib/acpi.c
@@ -260,11 +260,11 @@ static bool acpi_padding_is_safe(uint64_t base, uint64_t length) {
return true;
}
- uint64_t top = base + length;
+ uint64_t top = CHECKED_ADD(base, length, return false);
for (size_t i = 0; i < memmap_entries; i++) {
uint64_t entry_base = memmap[i].base;
- uint64_t entry_top = entry_base + memmap[i].length;
+ uint64_t entry_top = CHECKED_ADD(entry_base, memmap[i].length, continue);
if (entry_base >= top || entry_top <= base) {
continue;
diff --git a/common/lib/elf.c b/common/lib/elf.c
index ee686bd3..cfe5b6f6 100644
--- a/common/lib/elf.c
+++ b/common/lib/elf.c
@@ -887,10 +887,8 @@ bool elf64_load(uint8_t *elf, size_t file_size, uint64_t *entry_point, uint64_t
}
}
- uint64_t phdr_end;
- if (__builtin_add_overflow(phdr->p_vaddr, phdr->p_memsz, &phdr_end)) {
- panic(true, "elf: p_vaddr + p_memsz overflow in PHDR %u", i);
- }
+ uint64_t phdr_end = CHECKED_ADD(phdr->p_vaddr, phdr->p_memsz,
+ panic(true, "elf: p_vaddr + p_memsz overflow in PHDR %u", i));
// check for overlapping phdrs
for (uint16_t j = 0; j < hdr->ph_num; j++) {
@@ -910,10 +908,8 @@ bool elf64_load(uint8_t *elf, size_t file_size, uint64_t *entry_point, uint64_t
continue;
}
- uint64_t phdr_in_end;
- if (__builtin_add_overflow(phdr_in->p_vaddr, phdr_in->p_memsz, &phdr_in_end)) {
- panic(true, "elf: p_vaddr + p_memsz overflow in PHDR %u", j);
- }
+ uint64_t phdr_in_end = CHECKED_ADD(phdr_in->p_vaddr, phdr_in->p_memsz,
+ panic(true, "elf: p_vaddr + p_memsz overflow in PHDR %u", j));
if ((phdr_in->p_vaddr >= phdr->p_vaddr
&& phdr_in->p_vaddr < phdr_end)
@@ -994,10 +990,8 @@ again:
}
// Validate p_offset + p_filesz doesn't overflow or exceed file size
- uint64_t offset_end;
- if (__builtin_add_overflow(phdr->p_offset, phdr->p_filesz, &offset_end)) {
- panic(true, "elf: p_offset + p_filesz overflow");
- }
+ uint64_t offset_end = CHECKED_ADD(phdr->p_offset, phdr->p_filesz,
+ panic(true, "elf: p_offset + p_filesz overflow"));
if (offset_end > file_size) {
panic(true, "elf: p_offset + p_filesz exceeds file size");
}
@@ -1005,7 +999,8 @@ again:
uint64_t load_addr = *physical_base + (phdr->p_vaddr - *virtual_base);
#if defined (__aarch64__)
- uint64_t this_top = load_addr + phdr->p_memsz;
+ uint64_t this_top = CHECKED_ADD(load_addr, phdr->p_memsz,
+ panic(true, "elf: load_addr + p_memsz overflow"));
uint64_t mem_base, mem_size;
@@ -1082,7 +1077,8 @@ bool elf32_load_elsewhere(uint8_t *elf, size_t file_size, uint64_t *entry_point,
min_paddr = phdr->p_paddr;
}
- uint64_t top = (uint64_t)phdr->p_paddr + phdr->p_memsz;
+ uint64_t top = CHECKED_ADD((uint64_t)phdr->p_paddr, phdr->p_memsz,
+ panic(true, "elf: p_paddr + p_memsz overflow"));
if (top > max_paddr) {
max_paddr = top;
}
@@ -1107,7 +1103,9 @@ bool elf32_load_elsewhere(uint8_t *elf, size_t file_size, uint64_t *entry_point,
if (phdr->p_filesz > phdr->p_memsz) {
panic(true, "elf: p_filesz > p_memsz");
}
- if ((uint64_t)phdr->p_offset + phdr->p_filesz > file_size) {
+ uint64_t offset_end = CHECKED_ADD((uint64_t)phdr->p_offset, phdr->p_filesz,
+ panic(true, "elf: p_offset + p_filesz overflow"));
+ if (offset_end > file_size) {
panic(true, "elf: p_offset + p_filesz exceeds file size");
}
@@ -1115,7 +1113,7 @@ bool elf32_load_elsewhere(uint8_t *elf, size_t file_size, uint64_t *entry_point,
if (!entry_adjusted
&& *entry_point >= phdr->p_vaddr
- && *entry_point < (phdr->p_vaddr + phdr->p_memsz)) {
+ && *entry_point < CHECKED_ADD(phdr->p_vaddr, phdr->p_memsz, continue)) {
*entry_point -= phdr->p_vaddr;
*entry_point += phdr->p_paddr;
entry_adjusted = true;
@@ -1160,10 +1158,8 @@ bool elf64_load_elsewhere(uint8_t *elf, size_t file_size, uint64_t *entry_point,
min_paddr = phdr->p_paddr;
}
- uint64_t top;
- if (__builtin_add_overflow(phdr->p_paddr, phdr->p_memsz, &top)) {
- panic(true, "elf: p_paddr + p_memsz overflow");
- }
+ uint64_t top = CHECKED_ADD(phdr->p_paddr, phdr->p_memsz,
+ panic(true, "elf: p_paddr + p_memsz overflow"));
if (top > max_paddr) {
max_paddr = top;
}
@@ -1188,9 +1184,9 @@ bool elf64_load_elsewhere(uint8_t *elf, size_t file_size, uint64_t *entry_point,
if (phdr->p_filesz > phdr->p_memsz) {
panic(true, "elf: p_filesz > p_memsz");
}
- uint64_t offset_end;
- if (__builtin_add_overflow(phdr->p_offset, phdr->p_filesz, &offset_end)
- || offset_end > file_size) {
+ uint64_t offset_end = CHECKED_ADD(phdr->p_offset, phdr->p_filesz,
+ panic(true, "elf: p_offset + p_filesz overflow"));
+ if (offset_end > file_size) {
panic(true, "elf: p_offset + p_filesz exceeds file size");
}
@@ -1198,7 +1194,7 @@ bool elf64_load_elsewhere(uint8_t *elf, size_t file_size, uint64_t *entry_point,
if (!entry_adjusted
&& *entry_point >= phdr->p_vaddr
- && *entry_point < (phdr->p_vaddr + phdr->p_memsz)) {
+ && *entry_point < CHECKED_ADD(phdr->p_vaddr, phdr->p_memsz, continue)) {
*entry_point -= phdr->p_vaddr;
*entry_point += phdr->p_paddr;
entry_adjusted = true;
diff --git a/common/lib/misc.s2.c b/common/lib/misc.s2.c
index 78cdb881..5dbb29fe 100644
--- a/common/lib/misc.s2.c
+++ b/common/lib/misc.s2.c
@@ -44,11 +44,11 @@ uint64_t strtoui(const char *s, const char **end, int base) {
*end = &s[i];
return UINT64_MAX;
}
- if (__builtin_add_overflow(mul_result, (uint64_t)d, &n)) {
+ n = CHECKED_ADD(mul_result, (uint64_t)d, ({
if (end != NULL)
*end = &s[i];
return UINT64_MAX;
- }
+ }));
}
return n;
}
diff --git a/common/lib/part.s2.c b/common/lib/part.s2.c
index 422ec89b..8d61c932 100644
--- a/common/lib/part.s2.c
+++ b/common/lib/part.s2.c
@@ -39,10 +39,7 @@ static bool cache_block(struct volume *volume, uint64_t block) {
if (__builtin_mul_overflow(block, volume->fastest_xfer_size, &block_offset)) {
return false;
}
- uint64_t read_sector;
- if (__builtin_add_overflow(first_sect, block_offset, &read_sector)) {
- return false;
- }
+ uint64_t read_sector = CHECKED_ADD(first_sect, block_offset, return false);
// Clamp xfer_size to remaining sectors in volume
if (volume->sect_count != (uint64_t)-1) {
@@ -227,9 +224,7 @@ static int gpt_get_part(struct volume *ret, struct volume *volume, int partition
}
// Use actual entry size from header for offset calculation
uint64_t partition_offset = (uint64_t)partition * entry_size;
- if (__builtin_add_overflow(entry_offset, partition_offset, &entry_offset)) {
- return INVALID_TABLE; // Addition overflow would occur
- }
+ entry_offset = CHECKED_ADD(entry_offset, partition_offset, return INVALID_TABLE);
struct gpt_entry entry = {0};
if (!volume_read(volume, &entry, entry_offset, sizeof(entry))) {
@@ -428,17 +423,9 @@ static int mbr_get_logical_part(struct volume *ret, struct volume *extended_part
}
// Check for overflow in first_sect calculation
- uint64_t first_sect_64;
- if (__builtin_add_overflow(extended_part->first_sect, ebr_sector, &first_sect_64)) {
- return NO_PARTITION; // Addition overflow
- }
- if (__builtin_add_overflow(first_sect_64, (uint64_t)entry.first_sect, &first_sect_64)) {
- return NO_PARTITION; // Addition overflow
- }
- uint64_t partition_end;
- if (__builtin_add_overflow(first_sect_64, (uint64_t)entry.sect_count, &partition_end)) {
- return NO_PARTITION; // Partition would overflow
- }
+ uint64_t first_sect_64 = CHECKED_ADD(extended_part->first_sect, ebr_sector, return NO_PARTITION);
+ first_sect_64 = CHECKED_ADD(first_sect_64, (uint64_t)entry.first_sect, return NO_PARTITION);
+ (void)CHECKED_ADD(first_sect_64, (uint64_t)entry.sect_count, return NO_PARTITION);
#if defined (UEFI)
ret->efi_handle = extended_part->efi_handle;
diff --git a/common/protos/limine.c b/common/protos/limine.c
index f2fe591d..475ce4e5 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -79,7 +79,7 @@ static uint64_t get_hhdm_span_top(int base_revision) {
uint64_t base = memmap[i].base;
uint64_t length = memmap[i].length;
- uint64_t top = base + length;
+ uint64_t top = CHECKED_ADD(base, length, continue);
if (base_revision < 3 && base < 0x100000000) {
base = 0x100000000;
@@ -123,7 +123,7 @@ static pagemap_t build_identity_map(void) {
uint64_t base = _memmap[i].base;
uint64_t length = _memmap[i].length;
- uint64_t top = base + length;
+ uint64_t top = CHECKED_ADD(base, length, continue);
if (base < 0x100000000) {
base = 0x100000000;
@@ -226,7 +226,7 @@ static pagemap_t build_pagemap(int base_revision,
uint64_t base = _memmap[i].base;
uint64_t length = _memmap[i].length;
- uint64_t top = base + length;
+ uint64_t top = CHECKED_ADD(base, length, goto flush);
if (base_revision < 3 && base < 0x100000000) {
base = 0x100000000;
@@ -272,7 +272,7 @@ flush:
uint64_t base = _memmap[i].base;
uint64_t length = _memmap[i].length;
- uint64_t top = base + length;
+ uint64_t top = CHECKED_ADD(base, length, continue);
uint64_t aligned_base = ALIGN_DOWN(base, 0x1000);
uint64_t aligned_top = ALIGN_UP(top, 0x1000);
@@ -1344,7 +1344,7 @@ FEAT_END
}
uint64_t fb_base = memmap[i].base;
- uint64_t fb_top = fb_base + memmap[i].length;
+ 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);
@@ -1359,7 +1359,7 @@ FEAT_END
}
uint64_t region_base = memmap[j].base;
- uint64_t region_top = region_base + memmap[j].length;
+ uint64_t region_top = CHECKED_ADD(region_base, memmap[j].length, continue);
// Check if this region overlaps with the framebuffer's page-aligned extent.
if (region_top <= fb_aligned_base || region_base >= fb_aligned_top) {
diff --git a/common/protos/linux_x86.c b/common/protos/linux_x86.c
index cce595ec..e99d46dc 100644
--- a/common/protos/linux_x86.c
+++ b/common/protos/linux_x86.c
@@ -442,9 +442,8 @@ noreturn void linux_load(char *config, char *cmdline) {
if ((module = uri_open(module_path)) == NULL)
panic(true, "linux: Failed to open module with path `%s`. Is the path correct?", module_path);
- if (__builtin_add_overflow(size_of_all_modules, module->size, &size_of_all_modules)) {
- panic(true, "linux: Total module size overflow");
- }
+ size_of_all_modules = CHECKED_ADD(size_of_all_modules, module->size,
+ panic(true, "linux: Total module size overflow"));
modules[i] = module;
}
diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c
index 18721cd3..d3fdf6e6 100644
--- a/common/protos/multiboot2.c
+++ b/common/protos/multiboot2.c
@@ -382,7 +382,7 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
case 0: case 1: // No preference / prefer lowest
reloc_ascend = true;
relocated_base = ALIGN_UP(reloc_tag.min_addr, reloc_tag.align);
- if (relocated_base + ranges->length > reloc_tag.max_addr) {
+ if (CHECKED_ADD(relocated_base, ranges->length, goto reloc_fail) > reloc_tag.max_addr) {
goto reloc_fail;
}
break;
@@ -399,13 +399,13 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
}
for (;;) {
- if (check_usable_memory(relocated_base, relocated_base + ranges->length)) {
+ if (check_usable_memory(relocated_base, CHECKED_ADD(relocated_base, ranges->length, goto reloc_fail))) {
break;
}
if (reloc_ascend) {
relocated_base += reloc_tag.align;
- if (relocated_base + ranges->length > reloc_tag.max_addr) {
+ if (CHECKED_ADD(relocated_base, ranges->length, goto reloc_fail) > reloc_tag.max_addr) {
goto reloc_fail;
}
} else {
