From d2b1579668effc27b6abedb81f078b87231f9755 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Sun, 24 Jul 2022 22:28:16 +0200 Subject: [PATCH] multiboot: Properly check elsewhere returns --- common/lib/elsewhere.c | 6 ++++++ common/protos/multiboot1.c | 18 ++++++++++++------ common/protos/multiboot2.c | 19 ++++++++++++------- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/common/lib/elsewhere.c b/common/lib/elsewhere.c index c27b74c1..063a538d 100644 --- a/common/lib/elsewhere.c +++ b/common/lib/elsewhere.c @@ -32,7 +32,13 @@ bool elsewhere_append( *target = ALIGN_UP(top, 4096); } + uint64_t max_retries = 0x10000; + retry: + if (max_retries-- == 0) { + return false; + } + for (size_t i = 0; i < *ranges_count; i++) { uint64_t t_top = *target + t_length; diff --git a/common/protos/multiboot1.c b/common/protos/multiboot1.c index 4dfa7900..071e5554 100644 --- a/common/protos/multiboot1.c +++ b/common/protos/multiboot1.c @@ -194,9 +194,11 @@ noreturn void multiboot1_load(char *config, char *cmdline) { void *mb1_info_raw = ext_mem_alloc(mb1_info_size); uint64_t mb1_info_final_loc = 0x10000; - elsewhere_append(true /* flexible target */, + if (!elsewhere_append(true /* flexible target */, ranges, &ranges_count, - mb1_info_raw, &mb1_info_final_loc, mb1_info_size); + mb1_info_raw, &mb1_info_final_loc, mb1_info_size)) { + panic(true, "multiboot1: Cannot allocate mb1 info"); + } size_t mb1_info_slide = (size_t)mb1_info_raw - mb1_info_final_loc; @@ -224,9 +226,11 @@ noreturn void multiboot1_load(char *config, char *cmdline) { uint64_t section = (uint64_t)-1; /* no target preference, use top */ - elsewhere_append(true /* flexible target */, + if (!elsewhere_append(true /* flexible target */, ranges, &ranges_count, - kernel + shdr->sh_offset, §ion, shdr->sh_size); + kernel + shdr->sh_offset, §ion, shdr->sh_size)) { + panic(true, "multiboot1: Cannot allocate elf sections"); + } shdr->sh_addr = section; } @@ -265,9 +269,11 @@ noreturn void multiboot1_load(char *config, char *cmdline) { void *module_addr = freadall(f, MEMMAP_BOOTLOADER_RECLAIMABLE); uint64_t module_target = (uint64_t)-1; /* no target preference, use top */ - elsewhere_append(true /* flexible target */, + if (!elsewhere_append(true /* flexible target */, ranges, &ranges_count, - module_addr, &module_target, f->size); + module_addr, &module_target, f->size)) { + panic(true, "multiboot1: Cannot allocate module"); + } m->begin = module_target; m->end = m->begin + f->size; diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c index 5ee28c3b..d12707f0 100644 --- a/common/protos/multiboot2.c +++ b/common/protos/multiboot2.c @@ -327,9 +327,11 @@ noreturn void multiboot2_load(char *config, char* cmdline) { uint8_t *mb2_info = ext_mem_alloc(mb2_info_size); uint64_t mb2_info_final_loc = 0x10000; - elsewhere_append(true /* flexible target */, + if (!elsewhere_append(true /* flexible target */, ranges, &ranges_count, - mb2_info, &mb2_info_final_loc, mb2_info_size); + mb2_info, &mb2_info_final_loc, mb2_info_size)) { + panic(true, "multiboot2: Cannot allocate mb2 info"); + } struct multiboot2_start_tag *mbi_start = (struct multiboot2_start_tag *)mb2_info; info_idx += sizeof(struct multiboot2_start_tag); @@ -363,9 +365,11 @@ noreturn void multiboot2_load(char *config, char* cmdline) { uint64_t section = (uint64_t)-1; /* no target preference, use top */ - elsewhere_append(true /* flexible target */, + if (!elsewhere_append(true /* flexible target */, ranges, &ranges_count, - kernel + shdr->sh_offset, §ion, shdr->sh_size); + kernel + shdr->sh_offset, §ion, shdr->sh_size)) { + panic(true, "multiboot2: Cannot allocate elf sections"); + } shdr->sh_addr = section; } @@ -402,7 +406,6 @@ noreturn void multiboot2_load(char *config, char* cmdline) { if ((f = uri_open(module_path)) == NULL) panic(true, "multiboot2: Failed to open module with path `%s`. Is the path correct?", module_path); - // Module commandline can be null, so we guard against that and make the // string "". char *module_cmdline = conf_tuple.value2; @@ -411,9 +414,11 @@ noreturn void multiboot2_load(char *config, char* cmdline) { void *module_addr = freadall(f, MEMMAP_BOOTLOADER_RECLAIMABLE); uint64_t module_target = (uint64_t)-1; - elsewhere_append(true /* flexible target */, + if (!elsewhere_append(true /* flexible target */, ranges, &ranges_count, - module_addr, &module_target, f->size); + module_addr, &module_target, f->size)) { + panic(true, "multiboot2: Cannot allocate module"); + } struct multiboot_tag_module *module_tag = (struct multiboot_tag_module *)(mb2_info + info_idx);