summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2021-11-03 07:38:30 +0000
committerdzwdz2021-11-03 07:38:30 +0000
commitd7225aa75814788828387ad5871b6aa1dddf2cec (patch)
tree137851b58c1fe771363901e205f3a82029e649c1 /src
parent6d3960c8fdd361af32f88e4fb1e2deb892166932 (diff)
kernel: implement virt_cpy2kmalloc
Diffstat (limited to 'src')
-rw-r--r--src/kernel/mem/virt.h13
-rw-r--r--src/kernel/syscalls.c12
2 files changed, 18 insertions, 7 deletions
diff --git a/src/kernel/mem/virt.h b/src/kernel/mem/virt.h
index 3a42e9e..b858bdd 100644
--- a/src/kernel/mem/virt.h
+++ b/src/kernel/mem/virt.h
@@ -1,5 +1,6 @@
/* contains utilities for interacting with virtual memory */
#pragma once
+#include <kernel/mem/alloc.h>
#include <shared/types.h>
#include <stdbool.h>
#include <stddef.h>
@@ -38,3 +39,15 @@ static inline bool virt_cpy_from(struct pagedir *src_pages, // virtual -> physic
void *dest, const void __user *src, size_t length) {
return virt_cpy(NULL, (userptr_t)dest, src_pages, src, length);
}
+
+/** Copies a chunk of virtual memory to a newly kmalloc'd buffer. */
+static inline void *virt_cpy2kmalloc(struct pagedir *src_pages,
+ const void __user *src, size_t length) {
+ void *buf = kmalloc(length);
+ if (virt_cpy_from(src_pages, buf, src, length)) {
+ return buf;
+ } else {
+ kfree(buf);
+ return NULL;
+ }
+}
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 22bf1f6..a819b64 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -49,10 +49,8 @@ handle_t _syscall_open(const char __user *path, int len) {
if (process_find_handle(process_current) < 0)
return -1;
- // copy the path to the kernel, simplify it
- path_buf = kmalloc(len); // gets freed in vfs_request_finish
- if (!virt_cpy_from(process_current->pages, path_buf, path, len))
- goto fail;
+ path_buf = virt_cpy2kmalloc(process_current->pages, path, len);
+ if (!path_buf) goto fail;
len = path_simplify(path_buf, path_buf, len);
if (len < 0) goto fail;
@@ -90,9 +88,9 @@ int _syscall_mount(handle_t handle, const char __user *path, int len) {
if (PATH_MAX < len) return -1;
// copy the path to the kernel to simplify it
- path_buf = kmalloc(len);
- if (!virt_cpy_from(process_current->pages, path_buf, path, len))
- goto fail;
+ path_buf = virt_cpy2kmalloc(process_current->pages, path, len);
+ if (!path_buf) goto fail;
+
len = path_simplify(path_buf, path_buf, len);
if (len < 0) goto fail;