summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2022-05-01 20:21:55 +0200
committerdzwdz2022-05-01 20:21:55 +0200
commit5f6767972f1550c54dd6f28267dc3d882f67d7ed (patch)
tree0e16411f440e191084a6e61c81fd5416425ba12e
parentd996f88bfda890df5d2b76e7c06cae329e04ab00 (diff)
kernel/proc: `process_handle_get` for safely accepting handle ids
-rw-r--r--src/kernel/handle.h1
-rw-r--r--src/kernel/proc.c9
-rw-r--r--src/kernel/proc.h1
-rw-r--r--src/kernel/syscalls.c25
4 files changed, 20 insertions, 16 deletions
diff --git a/src/kernel/handle.h b/src/kernel/handle.h
index 86c1dbe..df5ad36 100644
--- a/src/kernel/handle.h
+++ b/src/kernel/handle.h
@@ -3,6 +3,7 @@
#include <shared/types.h>
#include <stddef.h>
+// TODO make accessible only from proc.c
#define HANDLE_MAX 16
enum handle_type {
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 79c4ed7..39f9e1f 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -208,6 +208,15 @@ handle_t process_find_handle(struct process *proc, handle_t start_at) {
return handle;
}
+struct handle*
+process_handle_get(struct process *p, handle_t id, enum handle_type type) {
+ struct handle *h;
+ if (id < 0 || id >= HANDLE_MAX) return NULL;
+ h = p->handles[id];
+ if (h == NULL || h->type != type) return NULL;
+ return h;
+}
+
void process_transition(struct process *p, enum process_state state) {
enum process_state last = p->state;
p->state = state;
diff --git a/src/kernel/proc.h b/src/kernel/proc.h
index 7e3cdd3..80cb4a3 100644
--- a/src/kernel/proc.h
+++ b/src/kernel/proc.h
@@ -76,6 +76,7 @@ struct process *process_find(enum process_state);
size_t process_find_multiple(enum process_state, struct process **buf, size_t max);
handle_t process_find_handle(struct process *proc, handle_t start_at); // finds the first free handle
+struct handle *process_handle_get(struct process *, handle_t, enum handle_type);
void process_transition(struct process *, enum process_state);
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index b6d1007..285ce58 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -81,7 +81,7 @@ fail:
return -1;
}
-int _syscall_mount(handle_t handle, const char __user *path, int len) {
+int _syscall_mount(handle_t hid, const char __user *path, int len) {
struct vfs_mount *mount = NULL;
struct vfs_backend *backend = NULL;
char *path_buf = NULL;
@@ -102,15 +102,10 @@ int _syscall_mount(handle_t handle, const char __user *path, int len) {
len--;
}
- if (handle >= 0) { // mounting a real backend?
- // TODO macro/function for validating handles, this is ridiculous
- if (handle >= HANDLE_MAX)
- goto fail;
- if (!process_current->handles[handle])
- goto fail;
- if (process_current->handles[handle]->type != HANDLE_FS_FRONT)
- goto fail;
- backend = process_current->handles[handle]->fs.backend;
+ if (hid >= 0) { // mounting a real backend?
+ struct handle *handle = process_handle_get(process_current, hid, HANDLE_FS_FRONT);
+ if (!handle) goto fail;
+ backend = handle->fs.backend;
} // otherwise backend == NULL
// append to mount list
@@ -129,9 +124,8 @@ fail:
}
int _syscall_read(handle_t handle_num, void __user *buf, size_t len, int offset) {
- if (handle_num < 0 || handle_num >= HANDLE_MAX) return -1;
- struct handle *handle = process_current->handles[handle_num];
- if (handle == NULL || handle->type != HANDLE_FILE) return -1;
+ struct handle *handle = process_handle_get(process_current, handle_num, HANDLE_FILE);
+ if (!handle) return -1;
return vfs_request_create((struct vfs_request) {
.type = VFSOP_READ,
.output = {
@@ -146,9 +140,8 @@ int _syscall_read(handle_t handle_num, void __user *buf, size_t len, int offset)
}
int _syscall_write(handle_t handle_num, const void __user *buf, size_t len, int offset) {
- if (handle_num < 0 || handle_num >= HANDLE_MAX) return -1;
- struct handle *handle = process_current->handles[handle_num];
- if (handle == NULL || handle->type != HANDLE_FILE) return -1;
+ struct handle *handle = process_handle_get(process_current, handle_num, HANDLE_FILE);
+ if (!handle) return -1;
return vfs_request_create((struct vfs_request) {
.type = VFSOP_WRITE,
.input = {