From 87ced72dde40b870256ea5bd3f0835d12efa3a23 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Fri, 22 Oct 2021 16:37:17 +0200 Subject: [PATCH] protos: Fix misc use-after-close bugs --- stage23/protos/linux.c | 20 +++++++++++--------- stage23/protos/multiboot1.c | 4 +++- stage23/protos/multiboot2.c | 4 +++- stage23/protos/stivale.c | 4 +++- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/stage23/protos/linux.c b/stage23/protos/linux.c index 62716bbf..21ba635c 100644 --- a/stage23/protos/linux.c +++ b/stage23/protos/linux.c @@ -346,17 +346,17 @@ struct boot_params { // End of Linux code void linux_load(char *config, char *cmdline) { - struct file_handle *kernel; + struct file_handle *kernel_file; char *kernel_path = config_get_value(config, 0, "KERNEL_PATH"); if (kernel_path == NULL) panic("linux: KERNEL_PATH not specified"); - if ((kernel = uri_open(kernel_path)) == NULL) + if ((kernel_file = uri_open(kernel_path)) == NULL) panic("linux: Failed to open kernel with path `%s`. Is the path correct?", kernel_path); uint32_t signature; - fread(kernel, &signature, 0x202, sizeof(uint32_t)); + fread(kernel_file, &signature, 0x202, sizeof(uint32_t)); // validate signature if (signature != 0x53726448) { @@ -364,7 +364,7 @@ void linux_load(char *config, char *cmdline) { } size_t setup_code_size = 0; - fread(kernel, &setup_code_size, 0x1f1, 1); + fread(kernel_file, &setup_code_size, 0x1f1, 1); if (setup_code_size == 0) setup_code_size = 4; @@ -379,11 +379,11 @@ void linux_load(char *config, char *cmdline) { size_t setup_header_end = ({ uint8_t x; - fread(kernel, &x, 0x201, 1); + fread(kernel_file, &x, 0x201, 1); 0x202 + x; }); - fread(kernel, setup_header, 0x1f1, setup_header_end - 0x1f1); + fread(kernel_file, setup_header, 0x1f1, setup_header_end - 0x1f1); printv("linux: Boot protocol: %u.%u\n", setup_header->version >> 8, setup_header->version & 0xff); @@ -400,7 +400,7 @@ void linux_load(char *config, char *cmdline) { if (verbose) { char *kernel_version = ext_mem_alloc(128); if (setup_header->kernel_version != 0) { - fread(kernel, kernel_version, setup_header->kernel_version + 0x200, 128); + fread(kernel_file, kernel_version, setup_header->kernel_version + 0x200, 128); print("linux: Kernel version: %s\n", kernel_version); } pmm_free(kernel_version, 128); @@ -419,13 +419,15 @@ void linux_load(char *config, char *cmdline) { print("linux: Loading kernel `%s`...\n", kernel_path); for (;;) { if (memmap_alloc_range(kernel_load_addr, - ALIGN_UP(kernel->size - real_mode_code_size, 4096), + ALIGN_UP(kernel_file->size - real_mode_code_size, 4096), MEMMAP_BOOTLOADER_RECLAIMABLE, true, false, false, false)) break; kernel_load_addr += 0x100000; } - fread(kernel, (void *)kernel_load_addr, real_mode_code_size, kernel->size - real_mode_code_size); + fread(kernel_file, (void *)kernel_load_addr, real_mode_code_size, kernel_file->size - real_mode_code_size); + + fclose(kernel_file); /////////////////////////////////////// // Modules diff --git a/stage23/protos/multiboot1.c b/stage23/protos/multiboot1.c index 727e02aa..ce3582e2 100644 --- a/stage23/protos/multiboot1.c +++ b/stage23/protos/multiboot1.c @@ -37,6 +37,8 @@ void multiboot1_load(char *config, char *cmdline) { uint8_t *kernel = freadall(kernel_file, MEMMAP_KERNEL_AND_MODULES); + size_t kernel_file_size = kernel_file->size; + fclose(kernel_file); struct multiboot1_header header = {0}; @@ -70,7 +72,7 @@ void multiboot1_load(char *config, char *cmdline) { if (header.load_end_addr) load_size = header.load_end_addr - header.load_addr; else - load_size = kernel_file->size; + load_size = kernel_file_size; memmap_alloc_range(header.load_addr, load_size, MEMMAP_KERNEL_AND_MODULES, true, true, false, false); memcpy((void *)(uintptr_t)header.load_addr, kernel + (header_offset diff --git a/stage23/protos/multiboot2.c b/stage23/protos/multiboot2.c index 09236623..3b0d29ec 100644 --- a/stage23/protos/multiboot2.c +++ b/stage23/protos/multiboot2.c @@ -92,6 +92,8 @@ void multiboot2_load(char *config, char* cmdline) { uint8_t *kernel = freadall(kernel_file, MEMMAP_KERNEL_AND_MODULES); + size_t kernel_file_size = kernel_file->size; + fclose(kernel_file); struct multiboot_header *header = load_multiboot2_header(kernel); @@ -190,7 +192,7 @@ void multiboot2_load(char *config, char* cmdline) { if (addresstag->load_end_addr) load_size = addresstag->load_end_addr - addresstag->load_addr; else - load_size = kernel_file->size; + load_size = kernel_file_size; size_t header_offset = (size_t)header - (size_t)kernel; diff --git a/stage23/protos/stivale.c b/stage23/protos/stivale.c index 3dabb5d8..25aa23eb 100644 --- a/stage23/protos/stivale.c +++ b/stage23/protos/stivale.c @@ -92,11 +92,13 @@ void stivale_load(char *config, char *cmdline) { int bits = elf_bits(kernel); bool loaded_by_anchor = false; + size_t kernel_file_size = kernel_file->size; + fclose(kernel_file); if (bits == -1) { struct stivale_anchor *anchor; - if (!stivale_load_by_anchor((void **)&anchor, "STIVALE1 ANCHOR", kernel, kernel_file->size)) { + if (!stivale_load_by_anchor((void **)&anchor, "STIVALE1 ANCHOR", kernel, kernel_file_size)) { panic("stivale: Not a valid ELF or anchored file."); }