From e1789ffa14826e0c7378f974ac68c2c04ba8640c Mon Sep 17 00:00:00 2001 From: dzwdz Date: Sat, 11 Sep 2021 18:22:21 +0200 Subject: add some helper functions for copying between virtual and physical memory this was already possible, but now it's slightly safer --- src/kernel/mem/virt.c | 3 ++- src/kernel/mem/virt.h | 11 +++++++++++ src/kernel/syscalls.c | 9 +++------ 3 files changed, 16 insertions(+), 7 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/mem/virt.c b/src/kernel/mem/virt.c index e0d8e44..7a38a88 100644 --- a/src/kernel/mem/virt.c +++ b/src/kernel/mem/virt.c @@ -41,7 +41,8 @@ bool virt_iter_next(struct virt_iter *iter) { } } else { // "iterate" over physical memory - iter->frag = (void*) iter->_virt; + // the double cast supresses the warning about changing address spaces + iter->frag = (void*)(uintptr_t)iter->_virt; } iter->frag_len = partial; diff --git a/src/kernel/mem/virt.h b/src/kernel/mem/virt.h index 7dac887..78d0cb3 100644 --- a/src/kernel/mem/virt.h +++ b/src/kernel/mem/virt.h @@ -27,3 +27,14 @@ bool virt_iter_next(struct virt_iter *); bool virt_cpy( struct pagedir *dest_pages, void __user *dest, struct pagedir *src_pages, const void __user *src, size_t length); + + +inline bool virt_cpy_to(struct pagedir *dest_pages, // physical -> virtual + void __user *dest, const void *src, size_t length) { + return virt_cpy(dest_pages, dest, NULL, (userptr_t)src, length); +} + +inline bool virt_cpy_from(struct pagedir *src_pages, // virtual -> physical + void *dest, const void __user *src, size_t length) { + return virt_cpy(NULL, (userptr_t)dest, src_pages, src, length); +} diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index ab4fdbb..743d5c5 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -83,8 +83,7 @@ handle_t _syscall_open(const char __user *path, int len) { // it can handle copies to physical memory too, though // note 2: path_buf gets freed in vfs_backend_finish path_buf = kmalloc(len); - if (!virt_cpy(NULL, path_buf, - process_current->pages, path, len)) + if (!virt_cpy_from(process_current->pages, path_buf, path, len)) goto fail; len = path_simplify(path_buf, path_buf, len); @@ -118,8 +117,7 @@ int _syscall_mount(handle_t handle, const char __user *path, int len) { // copy the path to the kernel path_buf = kmalloc(len); - if (!virt_cpy(NULL, path_buf, - process_current->pages, path, len)) + if (!virt_cpy_from(process_current->pages, path_buf, path, len)) goto fail; // simplify it @@ -179,8 +177,7 @@ handle_t _syscall_fs_create(handle_t __user *back_user) { process_current->handles[back].type = HANDLE_FS_BACK; // copy the back handle to back_user - if (!virt_cpy(process_current->pages, back_user, - NULL, &back, sizeof(handle_t))) + if (!virt_cpy_to(process_current->pages, back_user, &back, sizeof(back))) goto fail; backend = kmalloc(sizeof *backend); // TODO never freed -- cgit v1.2.3