:: commit 2a2582351acec4ffd31e1c0a1f5ab2531cb1fec0

mintsuki <mintsuki@protonmail.com> — 2021-10-22 14:37

parents: e7b18be6d9

protos: Fix misc use-after-close bugs

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.");
         }
 
tab: 248 wrap: offon