Add out of memory checks

This commit is contained in:
mintsuki 2020-05-02 23:38:57 +02:00
parent adb083e107
commit 62d78d1f90
9 changed files with 50 additions and 19 deletions

Binary file not shown.

View File

@ -7,6 +7,25 @@
#include <drivers/vga_textmode.h>
#include <lib/real.h>
#include <lib/cio.h>
#include <lib/e820.h>
// Checks if a given memory range is entirely within a usable e820 entry.
// TODO: Consider the possibility of adjacent usable entries.
// TODO: Consider the possibility of usable entry being overlapped by non-usable
// ones.
void is_valid_memory_range(size_t base, size_t size) {
for (size_t i = 0; i < e820_entries; i++) {
if (e820_map[i].type != 1)
continue;
size_t entry_base = e820_map[i].base;
size_t entry_top = e820_map[i].base + e820_map[i].length;
size_t limit = base + size;
if (base >= entry_base && base < entry_top &&
limit >= entry_base && limit < entry_top)
return;
}
panic("Out of memory");
}
uint8_t bcd_to_int(uint8_t val) {
return (val & 0x0f) + ((val & 0xf0) >> 4) * 10;

View File

@ -4,6 +4,8 @@
#include <stddef.h>
#include <stdint.h>
void is_valid_memory_range(size_t base, size_t size);
uint8_t bcd_to_int(uint8_t val);
int cpuid(uint32_t leaf, uint32_t subleaf,

View File

@ -1,8 +1,11 @@
#include <stdint.h>
#include <stddef.h>
#include <lib/e820.h>
#include <lib/real.h>
#include <lib/blib.h>
struct e820_entry_t *e820_map;
size_t e820_entries;
static const char *e820_type(uint32_t type) {
switch (type) {
@ -21,13 +24,11 @@ static const char *e820_type(uint32_t type) {
}
}
int init_e820(void) {
void init_e820(void) {
struct rm_regs r = {0};
int entry_count;
e820_map = balloc(sizeof(struct e820_entry_t));
for (int i = 0; ; i++) {
for (size_t i = 0; ; i++) {
struct e820_entry_t entry;
r.eax = 0xe820;
@ -39,25 +40,23 @@ int init_e820(void) {
e820_map[i] = entry;
if (r.eflags & EFLAGS_CF) {
entry_count = i;
e820_entries = i;
break;
}
if (!r.ebx) {
entry_count = ++i;
e820_entries = ++i;
break;
}
balloc(sizeof(struct e820_entry_t));
}
for (int i = 0; i < entry_count; i++) {
for (size_t i = 0; i < e820_entries; i++) {
print("e820: [%X -> %X] : %X <%s>\n",
e820_map[i].base,
e820_map[i].base + e820_map[i].length,
e820_map[i].length,
e820_type(e820_map[i].type));
}
return entry_count;
}

View File

@ -2,8 +2,7 @@
#define __LIB__E820_H__
#include <stdint.h>
#define E820_MAX_ENTRIES 256
#include <stddef.h>
struct e820_entry_t {
uint64_t base;
@ -13,7 +12,8 @@ struct e820_entry_t {
} __attribute__((packed));
extern struct e820_entry_t *e820_map;
extern size_t e820_entries;
int init_e820(void);
void init_e820(void);
#endif

View File

@ -243,8 +243,9 @@ int elf64_load(struct file_handle *fd, uint64_t *entry_point, uint64_t *top) {
if (this_top > *top)
*top = this_top;
fread(fd, (void *)(uint32_t)phdr.p_vaddr,
phdr.p_offset, phdr.p_filesz);
is_valid_memory_range((size_t)phdr.p_vaddr, (size_t)phdr.p_memsz);
fread(fd, (void *)(uint32_t)phdr.p_vaddr, phdr.p_offset, phdr.p_filesz);
size_t to_zero = (size_t)(phdr.p_memsz - phdr.p_filesz);
@ -292,6 +293,8 @@ int elf32_load(struct file_handle *fd, uint32_t *entry_point, uint32_t *top) {
if (this_top > *top)
*top = this_top;
is_valid_memory_range((size_t)phdr.p_paddr, (size_t)phdr.p_memsz);
fread(fd, (void *)phdr.p_paddr, phdr.p_offset, phdr.p_filesz);
size_t to_zero = (size_t)(phdr.p_memsz - phdr.p_filesz);

View File

@ -20,6 +20,7 @@ asm (
#include <lib/libc.h>
#include <lib/part.h>
#include <lib/config.h>
#include <lib/e820.h>
#include <fs/file.h>
#include <lib/elf.h>
#include <protos/stivale.h>
@ -149,6 +150,8 @@ void main(int boot_drive) {
}
got_entry:
init_e820();
if (!config_get_value(buf, 0, 32, "KERNEL_DRIVE")) {
drive = boot_drive;
} else {

View File

@ -7,6 +7,9 @@
#include <drivers/vga_textmode.h>
#include <lib/config.h>
#define KERNEL_LOAD_ADDR ((size_t)0x100000)
#define INITRD_LOAD_ADDR ((size_t)0x1000000)
void linux_load(struct file_handle *fd, char *cmdline) {
uint32_t signature;
fread(fd, &signature, 0x202, sizeof(uint32_t));
@ -70,7 +73,8 @@ void linux_load(struct file_handle *fd, char *cmdline) {
// load kernel
print("Loading kernel...\n");
fread(fd, (void *)0x100000, real_mode_code_size, fd->size - real_mode_code_size);
is_valid_memory_range(KERNEL_LOAD_ADDR, fd->size - real_mode_code_size);
fread(fd, (void *)KERNEL_LOAD_ADDR, real_mode_code_size, fd->size - real_mode_code_size);
char initrd_path[64];
if (!config_get_value(initrd_path, 0, 64, "INITRD_PATH"))
@ -88,10 +92,10 @@ void linux_load(struct file_handle *fd, char *cmdline) {
}
print("Loading initrd...\n");
size_t initrd_addr = 0x1000000;
fread(&initrd, (void *)initrd_addr, 0, initrd.size);
is_valid_memory_range(INITRD_LOAD_ADDR, initrd.size);
fread(&initrd, (void *)INITRD_LOAD_ADDR, 0, initrd.size);
*((uint32_t *)(real_mode_code + 0x218)) = (uint32_t)initrd_addr;
*((uint32_t *)(real_mode_code + 0x218)) = (uint32_t)INITRD_LOAD_ADDR;
*((uint32_t *)(real_mode_code + 0x21c)) = (uint32_t)initrd.size;
uint16_t real_mode_code_seg = rm_seg(real_mode_code);

View File

@ -97,7 +97,7 @@ void stivale_load(struct file_handle *fd, char *cmdline) {
print("stivale: Top used address in ELF: %X\n", top_used_addr);
stivale_struct.memory_map_entries = (uint64_t)init_e820();
stivale_struct.memory_map_entries = (uint64_t)e820_entries;
stivale_struct.memory_map_addr = (uint64_t)(size_t)e820_map;
stivale_struct.module_count = 0;
@ -126,6 +126,7 @@ void stivale_load(struct file_handle *fd, char *cmdline) {
((uint32_t)top_used_addr & ~((uint32_t)0xfff)) + 0x1000 :
(uint32_t)top_used_addr);
is_valid_memory_range((size_t)module_addr, f.size);
fread(&f, module_addr, 0, f.size);
m->begin = (uint64_t)(size_t)module_addr;