diff options
author | Marvin Borner | 2021-04-09 13:10:03 +0200 |
---|---|---|
committer | Marvin Borner | 2021-04-09 13:10:03 +0200 |
commit | eeb88df1d501ccec4737c18dddb7ca0a1176304f (patch) | |
tree | d36b563a27a4a7bdeae662eb5aa44ca082b57e0b /kernel/features | |
parent | f8d841fe268ebba43686729af535e035702438f7 (diff) |
Added readable/writable checks
Diffstat (limited to 'kernel/features')
-rw-r--r-- | kernel/features/fs.c | 28 | ||||
-rw-r--r-- | kernel/features/load.c | 6 | ||||
-rw-r--r-- | kernel/features/mm.c | 62 |
3 files changed, 58 insertions, 38 deletions
diff --git a/kernel/features/fs.c b/kernel/features/fs.c index ded4bf1..76c230e 100644 --- a/kernel/features/fs.c +++ b/kernel/features/fs.c @@ -119,10 +119,10 @@ static void vfs_list_mounts() res vfs_mount(struct device *dev, const char *path) { - if (!memory_valid(path)) + if (!memory_readable(path)) return -EFAULT; - if (!memory_valid(dev) || !dev->id) + if (!memory_readable(dev) || !dev->id) return -EFAULT; if (vfs_mounted(dev, path)) @@ -140,10 +140,10 @@ res vfs_mount(struct device *dev, const char *path) res vfs_read(const char *path, void *buf, u32 offset, u32 count) { - if (!memory_valid(path)) + if (!memory_readable(path)) return -EFAULT; - if (!memory_valid(buf)) + if (!memory_writable(buf)) return -EFAULT; struct mount_info *m = vfs_find_mount_info(path); @@ -168,10 +168,10 @@ res vfs_read(const char *path, void *buf, u32 offset, u32 count) res vfs_write(const char *path, void *buf, u32 offset, u32 count) { - if (!memory_valid(path)) + if (!memory_readable(path)) return -EFAULT; - if (!memory_valid(buf)) + if (!memory_writable(buf)) return -EFAULT; struct mount_info *m = vfs_find_mount_info(path); @@ -196,7 +196,7 @@ res vfs_write(const char *path, void *buf, u32 offset, u32 count) res vfs_ioctl(const char *path, u32 request, void *arg1, void *arg2, void *arg3) { - if (!memory_valid(path)) + if (!memory_readable(path)) return -EFAULT; struct mount_info *m = vfs_find_mount_info(path); @@ -218,10 +218,10 @@ res vfs_ioctl(const char *path, u32 request, void *arg1, void *arg2, void *arg3) res vfs_stat(const char *path, struct stat *buf) { - if (!memory_valid(path)) + if (!memory_readable(path)) return -EFAULT; - if (!memory_valid(buf)) + if (!memory_writable(buf)) return -EFAULT; struct mount_info *m = vfs_find_mount_info(path); @@ -243,7 +243,7 @@ res vfs_stat(const char *path, struct stat *buf) res vfs_block(const char *path, u32 func_ptr) { - if (!func_ptr || !memory_valid(path)) + if (!func_ptr || !memory_readable(path)) return -EFAULT; struct mount_info *m = vfs_find_mount_info(path); @@ -267,11 +267,11 @@ res vfs_block(const char *path, u32 func_ptr) // TODO: Fix page fault when called too often/fast res vfs_poll(const char **files) { - if (!memory_valid(files)) + if (!memory_readable(files)) return -EFAULT; stac(); - for (const char **p = files; *p && memory_valid(*p) && **p; p++) { + for (const char **p = files; *p && memory_readable(*p) && **p; p++) { res ready = vfs_ready(*p); clac(); if (ready == 1) @@ -281,7 +281,7 @@ res vfs_poll(const char **files) stac(); } - for (const char **p = files; *p && memory_valid(*p) && **p; p++) { + for (const char **p = files; *p && memory_readable(*p) && **p; p++) { vfs_block(*p, (u32)vfs_poll); stac(); } @@ -292,7 +292,7 @@ res vfs_poll(const char **files) res vfs_ready(const char *path) { - if (!memory_valid(path)) + if (!memory_readable(path)) return -EFAULT; struct mount_info *m = vfs_find_mount_info(path); diff --git a/kernel/features/load.c b/kernel/features/load.c index 91954b1..df01e04 100644 --- a/kernel/features/load.c +++ b/kernel/features/load.c @@ -11,7 +11,7 @@ res elf_load(const char *name, struct proc *proc) { - if (!memory_valid(name)) + if (!memory_readable(name)) return -EFAULT; stac(); @@ -52,7 +52,7 @@ res elf_load(const char *name, struct proc *proc) header.version != 1 || header.machine != ELF_MACHINE_386) return -ENOEXEC; - if (!memory_valid((void *)header.entry)) + if (!memory_is_user((void *)header.entry)) return -ENOEXEC; // ASLR @@ -77,7 +77,7 @@ res elf_load(const char *name, struct proc *proc) if (program.vaddr == 0 || program.type != ELF_PROGRAM_TYPE_LOAD) continue; - if (!memory_is_user(program.vaddr)) + if (!memory_is_user((void *)program.vaddr)) return -ENOEXEC; struct page_dir *prev; diff --git a/kernel/features/mm.c b/kernel/features/mm.c index 7baa4ea..466e448 100644 --- a/kernel/features/mm.c +++ b/kernel/features/mm.c @@ -199,7 +199,7 @@ void physical_free(struct memory_range range) #define PDI(vaddr) ((vaddr) >> 22) #define PTI(vaddr) (((vaddr) >> 12) & 0x03ff) -u8 virtual_present(struct page_dir *dir, u32 vaddr) +union page_table_entry *virtual_entry(struct page_dir *dir, u32 vaddr) { u32 pdi = PDI(vaddr); union page_dir_entry *dir_entry = &dir->entries[pdi]; @@ -210,24 +210,35 @@ u8 virtual_present(struct page_dir *dir, u32 vaddr) u32 pti = PTI(vaddr); union page_table_entry *table_entry = &table->entries[pti]; + if (!table_entry->bits.present) + return 0; - return table_entry->bits.present; + return table_entry; } -u32 virtual_to_physical(struct page_dir *dir, u32 vaddr) +u8 virtual_present(struct page_dir *dir, u32 vaddr) { - u32 pdi = PDI(vaddr); - union page_dir_entry *dir_entry = &dir->entries[pdi]; - if (!dir_entry->bits.present) - return 0; + union page_table_entry *table_entry = virtual_entry(dir, vaddr); + return !!table_entry; +} - struct page_table *table = (struct page_table *)(dir_entry->bits.address * PAGE_SIZE); +u8 virtual_user_readable(struct page_dir *dir, u32 vaddr) +{ + union page_table_entry *table_entry = virtual_entry(dir, vaddr); + return table_entry && table_entry->bits.user; +} - u32 pti = PTI(vaddr); - union page_table_entry *table_entry = &table->entries[pti]; - if (!table_entry->bits.present) - return 0; +u8 virtual_user_writable(struct page_dir *dir, u32 vaddr) +{ + union page_table_entry *table_entry = virtual_entry(dir, vaddr); + return table_entry && table_entry->bits.user && table_entry->bits.writable; +} +u32 virtual_to_physical(struct page_dir *dir, u32 vaddr) +{ + union page_table_entry *table_entry = virtual_entry(dir, vaddr); + if (!table_entry) + return 0; return (table_entry->bits.address * PAGE_SIZE) + (vaddr & (PAGE_SIZE - 1)); } @@ -457,7 +468,7 @@ void memory_map_identity(struct page_dir *dir, struct memory_range prange, u32 f static struct list *memory_objects = NULL; res memory_sys_alloc(struct page_dir *dir, u32 size, u32 *addr, u32 *id, u8 shared) { - if (!memory_valid(addr) || !memory_valid(id)) + if (!memory_writable(addr) || !memory_writable(id)) return -EFAULT; size = PAGE_ALIGN_UP(size); @@ -488,7 +499,7 @@ res memory_sys_alloc(struct page_dir *dir, u32 size, u32 *addr, u32 *id, u8 shar res memory_sys_free(struct page_dir *dir, u32 addr) { - if (!addr || !memory_valid((void *)addr)) + if (!addr || !memory_readable((void *)addr)) return -EFAULT; struct list *links = proc_current()->memory; @@ -516,7 +527,7 @@ res memory_sys_free(struct page_dir *dir, u32 addr) res memory_sys_shaccess(struct page_dir *dir, u32 id, u32 *addr, u32 *size) { - if (!memory_valid(addr) || !memory_valid(size)) + if (!memory_writable(addr) || !memory_writable(size)) return -EFAULT; struct node *iterator = memory_objects->head; @@ -576,16 +587,25 @@ void memory_bypass_disable(void) memory_bypass_validity = 0; } -u8 memory_is_user(u32 addr) +u8 memory_is_user(const void *addr) { - return PDI(addr) >= PAGE_KERNEL_COUNT; + return PDI((u32)addr) >= PAGE_KERNEL_COUNT; } -// TODO: Limit by proc stack and data range -u8 memory_valid(const void *addr) +u8 memory_readable(const void *addr) { - if (proc_current() && !memory_bypass_validity) - return memory_is_user((u32)addr); + struct proc *proc = proc_current(); + if (proc && !memory_bypass_validity) + return memory_is_user(addr) && virtual_user_readable(proc->page_dir, (u32)addr); + else + return 1; +} + +u8 memory_writable(const void *addr) +{ + struct proc *proc = proc_current(); + if (proc && !memory_bypass_validity) + return memory_is_user(addr) && virtual_user_writable(proc->page_dir, (u32)addr); else return 1; } |