summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-09-26 17:11:50 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-09-26 17:11:50 -0400
commit5f813d49a08cf3c3f8cf6c422cfb6587df575f62 (patch)
treebd8872ee24580614b3eb845e1de26d465b025a09 /sys
parentb6765812f7da9feccc271e8e0b06f166e8054386 (diff)
downloadjove-kernel-5f813d49a08cf3c3f8cf6c422cfb6587df575f62.tar.gz
jove-kernel-5f813d49a08cf3c3f8cf6c422cfb6587df575f62.tar.bz2
jove-kernel-5f813d49a08cf3c3f8cf6c422cfb6587df575f62.zip
add docs for syscalls. make syscall code kind-of cleaner
Diffstat (limited to 'sys')
-rw-r--r--sys/link.c56
-rw-r--r--sys/link.h24
-rw-r--r--sys/lockstack.c30
-rw-r--r--sys/lockstack.h18
-rw-r--r--sys/syscall.c105
-rw-r--r--sys/syscall.h45
-rw-r--r--sys/syscall_objdir.c19
-rw-r--r--sys/syscall_pagedir.c170
-rw-r--r--sys/syscall_untyped.c68
-rw-r--r--sys/syscall_vtt.c20
10 files changed, 368 insertions, 187 deletions
diff --git a/sys/link.c b/sys/link.c
index 5be9457..592fe8f 100644
--- a/sys/link.c
+++ b/sys/link.c
@@ -2,31 +2,23 @@
#include "arch/x86_64/hal/obj.h"
#include "hal/memory.h"
-void*
-obj_deref_linked(jove_owned_obj_t *obj)
+uint8_t
+link_gettype(jove_owned_obj_t *obj)
{
- switch(obj_gettype(obj)) {
- case JOVE_OBJ_LINK: return obj_deref_linked(link_deref(obj));
- default: return obj_deref(obj);
- }
+ return obj_gettype(link_deref(obj));
}
uint8_t
-obj_gettype_linked(jove_owned_obj_t *obj)
+link_getperm(jove_owned_obj_t *link)
{
- switch(obj_gettype(obj)) {
- case JOVE_OBJ_LINK: return obj_gettype_linked(link_deref(obj));
- default: return obj_gettype(obj);
- }
+ struct obj_link *linkval = obj_deref(link);
+ return linkval->permissions;
}
uint64_t
-obj_getvalue_linked(jove_owned_obj_t *obj)
+link_getvalue(jove_owned_obj_t *obj)
{
- switch(obj_gettype(obj)) {
- case JOVE_OBJ_LINK: return obj_getvalue_linked(link_deref(obj));
- default: return obj_getvalue(obj);
- }
+ return obj_getvalue(link_deref(obj));
}
jove_owned_obj_t*
@@ -36,11 +28,41 @@ link_deref(jove_owned_obj_t *link)
return obj_take(&linkval->obj);
}
-jove_owned_obj_t *link_new(jove_obj_t *tgt, jove_owned_obj_t *dst)
+jove_owned_obj_t*
+link_try_deref(jove_owned_obj_t *link)
+{
+ struct obj_link *linkval = obj_deref(link);
+ return obj_trytake(&linkval->obj);
+}
+
+jove_perm_obj_t
+link_traverse(jove_owned_obj_t *link, lockstack_t *lockstack)
+{
+ jove_perm_obj_t perm_obj = { .obj = link, .permissions = JOVE_PERM_ALL };
+ while(obj_gettype(perm_obj.obj) == JOVE_OBJ_LINK) {
+ perm_obj.permissions &= link_getperm(perm_obj.obj);
+ perm_obj.obj = lockstack_push(lockstack, link_deref(perm_obj.obj));
+ }
+ return perm_obj;
+}
+
+jove_perm_obj_t
+link_try_traverse(jove_owned_obj_t *link, lockstack_t *lockstack)
+{
+ jove_perm_obj_t perm_obj = { .obj = link, .permissions = JOVE_PERM_ALL };
+ while(perm_obj.obj != NULL && obj_gettype(perm_obj.obj) == JOVE_OBJ_LINK) {
+ perm_obj.permissions &= link_getperm(perm_obj.obj);
+ perm_obj.obj = lockstack_push(lockstack, link_deref(perm_obj.obj));
+ }
+ return perm_obj;
+}
+
+jove_owned_obj_t *link_new(jove_obj_t *tgt, jove_owned_obj_t *dst, uint16_t permissions)
{
struct obj_link *linkval = obj_deref(dst);
linkval->obj = *tgt;
linkval->refcount = 2;
+ linkval->permissions = permissions;
{
jove_owned_obj_t *tgt_owned = obj_take(tgt);
diff --git a/sys/link.h b/sys/link.h
index 37fa1e8..3f7331f 100644
--- a/sys/link.h
+++ b/sys/link.h
@@ -1,3 +1,4 @@
+#include "sys/lockstack.h"
#ifndef _JOVE_SYS_LINK_HPP
#define _JOVE_SYS_LINK_HPP 1
@@ -5,17 +6,28 @@
struct obj_link
{
- size_t refcount;
jove_obj_t obj;
+ uint16_t refcount;
+ uint8_t permissions;
};
-void *obj_deref_linked(jove_owned_obj_t *obj);
-uint8_t obj_gettype_linked(jove_owned_obj_t *obj);
-uint64_t obj_getvalue_linked(jove_owned_obj_t *obj);
+typedef struct obj_perm_group
+{
+ jove_owned_obj_t *obj;
+ uint8_t permissions;
+} jove_perm_obj_t;
+
+uint8_t link_gettype(jove_owned_obj_t *obj);
+uint8_t link_getperm(jove_owned_obj_t *link);
+uint64_t link_getvalue(jove_owned_obj_t *obj);
jove_owned_obj_t *link_deref(jove_owned_obj_t *link);
-jove_obj_t link_unlink(jove_owned_obj_t *link);
+jove_owned_obj_t *link_try_deref(jove_owned_obj_t *link);
-jove_owned_obj_t *link_new(jove_obj_t *tgt, jove_owned_obj_t *dst);
+jove_perm_obj_t link_traverse(jove_owned_obj_t *link, lockstack_t *lockstack);
+jove_perm_obj_t link_try_traverse(jove_owned_obj_t *link, lockstack_t *lockstack);
+
+jove_obj_t link_unlink(jove_owned_obj_t *link);
+jove_owned_obj_t *link_new(jove_obj_t *tgt, jove_owned_obj_t *dst, uint16_t permissions);
#endif
diff --git a/sys/lockstack.c b/sys/lockstack.c
new file mode 100644
index 0000000..7a419ac
--- /dev/null
+++ b/sys/lockstack.c
@@ -0,0 +1,30 @@
+#include "lockstack.h"
+#include "lib/printf.h"
+
+jove_owned_obj_t*
+lockstack_push(lockstack_t *stack, jove_owned_obj_t *obj)
+{
+ if(stack->depth == LOCKSTACK_MAX) {
+ klogf("lock stack exceeds %i entries\n", LOCKSTACK_MAX);
+ return NULL;
+ }
+ if(obj == NULL) return obj;
+
+ stack->stack[stack->depth++] = obj;
+ return obj;
+}
+
+jove_obj_t*
+lockstack_pop(lockstack_t *stack)
+{
+ return obj_release(stack->stack[--stack->depth]);
+}
+
+void
+lockstack_popall(lockstack_t *stack)
+{
+ for(size_t i = 0; i < stack->depth; i++)
+ obj_release(stack->stack[i]);
+ stack->depth = 0;
+}
+
diff --git a/sys/lockstack.h b/sys/lockstack.h
new file mode 100644
index 0000000..f41f9dc
--- /dev/null
+++ b/sys/lockstack.h
@@ -0,0 +1,18 @@
+#ifndef _JOVE_SYS_LOCKSTACK_H
+#define _JOVE_SYS_LOCKSTACK_H 1
+
+#include <stddef.h>
+#include "hal/obj.h"
+#include "config.h"
+
+typedef struct lockstack
+{
+ size_t depth;
+ jove_owned_obj_t *stack[LOCKSTACK_MAX];
+} lockstack_t;
+
+jove_owned_obj_t *lockstack_push(lockstack_t *stack, jove_owned_obj_t *obj);
+jove_obj_t *lockstack_pop(lockstack_t *stack);
+void lockstack_popall(lockstack_t *stack);
+
+#endif
diff --git a/sys/syscall.c b/sys/syscall.c
index 457b820..0da3475 100644
--- a/sys/syscall.c
+++ b/sys/syscall.c
@@ -24,28 +24,20 @@ int __syscall_generic_objpath(jove_owned_obj_t *objdir, size_t payload_bytes, vo
}
int
-_syscall_handle_generic(
- jove_owned_obj_t *pcb_obj,
- jove_owned_obj_t *objdir,
- jove_owned_obj_t *message_obj,
- jove_owned_obj_t *target_obj,
- struct syscall_header *header,
- size_t bytes_left,
- void *payload)
+_syscall_handle_generic(syscall_context_t *ctx)
{
- pcb_t *pcb = obj_deref(pcb_obj);
- klogf("Process %i encountered stub syscall on object %P\n", pcb_pid(pcb), header->path, header->pathlen);
- return EBADOBJ;
+ pcb_t *pcb = obj_deref(ctx->pcb);
+ klogf("Process %i encountered stub syscall on object %P\n", pcb_pid(pcb), ctx->header->path, ctx->header->pathlen);
+ return -EBADOBJ;
}
static const syscall_handle_t s_syscall_handles[128] = {
- [JOVE_OBJ_NONE] = NULL,
[JOVE_OBJ_UNTYPED] = _syscall_handle_untyped,
[JOVE_OBJ_OBJDIR] = _syscall_handle_objdir,
[JOVE_OBJ_PAGEDIR] = _syscall_handle_pagedir,
[JOVE_OBJ_PROCESSOR] = _syscall_handle_generic,
- [JOVE_OBJ_HWMEMORY] = _syscall_handle_generic,
- [JOVE_OBJ_PROCESS] = _syscall_handle_generic,
+ [JOVE_OBJ_SHMEMORY] = _syscall_handle_generic,
+ [JOVE_OBJ_PCB] = _syscall_handle_generic,
[JOVE_OBJ_INT_HANDLE] = _syscall_handle_generic,
[JOVE_OBJ_INITRD_FILE] = _syscall_handle_generic,
[JOVE_OBJ_FRAMEBUFFER] = _syscall_handle_generic,
@@ -55,36 +47,63 @@ static const syscall_handle_t s_syscall_handles[128] = {
};
int
+_syscall_handle_switch(syscall_context_t *ctx)
+{
+ uint8_t target_type = obj_gettype(ctx->target.obj);
+ if(target_type > 0x7F) {
+ return _syscall_handle_arch(ctx);
+ }
+ else {
+ syscall_handle_t call_handle = s_syscall_handles[target_type];
+ if(call_handle == NULL) {
+ klogf("Tried to call syscall on object %P which doesn't support syscalls!\n",
+ ctx->header->path, ctx->header->pathlen);
+ return -EBADOBJ;
+ }
+ else {
+ return call_handle(ctx);
+ }
+ }
+}
+
+int
syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
{
uint16_t *message_path = (uint16_t*)&message_path_raw;
if(message_pathlen > sizeof(uintmax_t) >> 1) {
- return EBADPATH;
+ return -EBADPATH;
}
- jove_owned_obj_t *pcb_obj = process_current();
- pcb_t *pcb = obj_deref(pcb_obj);
- jove_owned_obj_t *objdir = pcb_rootdir(pcb);
- jove_owned_obj_t *message_obj = objdir_trygetobj(objdir, message_path, message_pathlen);
+ syscall_context_t ctx;
+ ctx.lockstack.depth = 0;
int sysret = 0;
- if(message_obj == NULL) {
- klogf("Process %i tried to call syscall with bad message %P : %s\n",
+ ctx.pcb = lockstack_push(&ctx.lockstack, process_current());
+ pcb_t *pcb = obj_deref(ctx.pcb);
+ ctx.objdir = lockstack_push(&ctx.lockstack, obj_take(pcb_rootdir(pcb)));
+
+ ctx.message = link_try_traverse(
+ lockstack_push(&ctx.lockstack, objdir_trygetobj(
+ ctx.objdir, message_path, message_pathlen)),
+ &ctx.lockstack);
+
+ if(ctx.message.obj == NULL) {
+ klogf("Process %i failed to get message %P : %s\n",
pcb_pid(pcb), message_path, message_pathlen, errstr(errno));
sysret = -errno;
- goto release_premsg;
+ goto release_return;
}
- if(obj_gettype_linked(message_obj) != JOVE_OBJ_MESSAGE) {
+ if(obj_gettype(ctx.message.obj) != JOVE_OBJ_MESSAGE) {
klogf("Process %i tried to call syscall with invalid object %P\n",
pcb_pid(pcb), message_path, message_pathlen);
sysret = -EBADOBJ;
goto release_return;
}
- size_t messagelen = message_len(message_obj);
- void *messagedata = message_data(message_obj);
+ size_t messagelen = message_len(ctx.message.obj);
+ void *messagedata = message_data(ctx.message.obj);
struct syscall_header *header = messagedata;
size_t bytes_needed = sizeof(struct syscall_header) + header->pathlen * 2;
@@ -94,8 +113,14 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
sysret = -ETOOSMALL;
goto release_return;
}
- jove_owned_obj_t *target = objdir_trygetobj(objdir, header->path, header->pathlen);
- if(target == 0) {
+
+ ctx.header = header;
+ ctx.bytes_left = messagelen - bytes_needed;
+ ctx.payload = (void*)((uintptr_t)header + bytes_needed);
+
+ ctx.target.obj = lockstack_push(&ctx.lockstack,
+ objdir_trygetobj(ctx.objdir, header->path, header->pathlen));
+ if(ctx.target.obj == 0) {
//Could not find payload target in pcb rootdir.
klogf("Process %i tried to call syscall with bad target path %P : %s\n",
pcb_pid(pcb), header->path, header->pathlen, errstr(errno));
@@ -103,28 +128,10 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
goto release_return;
}
- uint8_t target_type = obj_gettype(target);
- size_t bytes_left = messagelen - bytes_needed;
- if(target_type > 0x7F) {
- sysret = _syscall_handle_arch(
- pcb_obj, objdir, message_obj, target,
- header, bytes_left, messagedata + bytes_needed);
- }else{
- syscall_handle_t call_handle = s_syscall_handles[obj_gettype(target)];
- if(call_handle == NULL) {
- klogf("Process %i tried to call syscall on object %P which doesn't support syscalls!\n",
- pcb_pid(pcb), header->path, header->pathlen);
- sysret = -EBADOBJ;
- }else
- sysret = call_handle(
- pcb_obj, objdir, message_obj, target,
- header, bytes_left, messagedata + bytes_needed);
- }
- obj_release(target);
+ ctx.target.permissions = JOVE_PERM_ALL;
+ sysret = _syscall_handle_switch(&ctx);
+
release_return:
- obj_release(message_obj);
-release_premsg:
- obj_release(objdir);
- obj_release(pcb_obj);
+ lockstack_popall(&ctx.lockstack);
return sysret;
}
diff --git a/sys/syscall.h b/sys/syscall.h
index 9f56447..e6358cb 100644
--- a/sys/syscall.h
+++ b/sys/syscall.h
@@ -1,8 +1,11 @@
#ifndef _JOVE_SYS_SYSCALL_H
#define _JOVE_SYS_SYSCALL_H 1
+#include "config.h"
#include "api/syscall.h"
#include "hal/obj.h"
+#include "lockstack.h"
+#include "link.h"
#include <stdint.h>
#define CHECK_TOOSMALL(required, present, fail_msg) \
@@ -20,29 +23,39 @@ do { if(obj == NULL) { \
#define CHECK_OBJTYPE(obj, type, fail_msg) \
do { if(obj_gettype(obj) != type) { \
kprintf("%s: %s\n", __func__, fail_msg); \
- obj_release(obj); \
return -EBADOBJ; \
} } while(0)
-#define SYSCALL_FUNCTION_ARGS \
- jove_owned_obj_t*, /*PCB object*/ \
- jove_owned_obj_t*, /*Objdir object*/ \
- jove_owned_obj_t*, /*Message object*/ \
- jove_owned_obj_t*, /*Target object*/ \
- struct syscall_header*, /*Syscall header*/ \
- size_t, /*How many bytes are left in the message*/ \
- void* /*The bytes left in the message.*/
+#define CHECK_OBJPERM(obj, perms, fail_msg) \
+ do { if((obj.permissions & perms) == 0) { \
+ kprintf("%s: %s\n", __func__, fail_msg); \
+ return -EPERM; \
+ } } while(0)
-typedef int (*syscall_handle_t)(SYSCALL_FUNCTION_ARGS);
+typedef struct syscall_state
+{
+ lockstack_t lockstack;
+ jove_owned_obj_t *pcb;
+ jove_owned_obj_t *objdir;
+ jove_perm_obj_t message;
+ jove_perm_obj_t target;
+ struct syscall_header *header;
+ size_t bytes_left;
+ void *payload;
+} syscall_context_t;
+
+typedef int (*syscall_handle_t)(syscall_context_t*);
int __syscall_generic_objpath(jove_owned_obj_t *objdir, size_t bytes_left, void *payload_data, jove_owned_obj_t **retobj);
-int _syscall_handle_generic(SYSCALL_FUNCTION_ARGS);
-int _syscall_handle_arch(SYSCALL_FUNCTION_ARGS);
+int _syscall_handle_switch(syscall_context_t *ctx);
+
+int _syscall_handle_generic(syscall_context_t *ctx);
+int _syscall_handle_arch(syscall_context_t *ctx);
-int _syscall_handle_vtt(SYSCALL_FUNCTION_ARGS);
-int _syscall_handle_objdir(SYSCALL_FUNCTION_ARGS);
-int _syscall_handle_untyped(SYSCALL_FUNCTION_ARGS);
-int _syscall_handle_pagedir(SYSCALL_FUNCTION_ARGS);
+int _syscall_handle_vtt(syscall_context_t *ctx);
+int _syscall_handle_objdir(syscall_context_t *ctx);
+int _syscall_handle_untyped(syscall_context_t *ctx);
+int _syscall_handle_pagedir(syscall_context_t *ctx);
#endif
diff --git a/sys/syscall_objdir.c b/sys/syscall_objdir.c
index 277639f..5a6786d 100644
--- a/sys/syscall_objdir.c
+++ b/sys/syscall_objdir.c
@@ -25,20 +25,15 @@ s_syscall_objdir_objtype(
}
int
-_syscall_handle_objdir(
- jove_owned_obj_t *pcb_obj,
- jove_owned_obj_t *objdir,
- jove_owned_obj_t *message_obj,
- jove_owned_obj_t *target_obj,
- struct syscall_header *header,
- size_t bytes_left,
- void *payload)
+_syscall_handle_objdir(syscall_context_t *ctx)
{
- switch(header->callid) {
+ switch(ctx->header->callid) {
case SYSCALL_OBJDIR_OBJTYPE:
- return s_syscall_objdir_objtype(objdir, target_obj, bytes_left, payload);
+ if(ctx->target.permissions & SYSCALL_PERM_OBJDIR_OBJTYPE)
+ return s_syscall_objdir_objtype(
+ ctx->objdir, ctx->target.obj, ctx->bytes_left, ctx->payload);
+ return -EPERM;
default:
- kprintf("syscall_handle_objdir: Objdir does not support syscall %i\n", header->callid);
- return EBADARG;
+ return -EBADCALL;
}
}
diff --git a/sys/syscall_pagedir.c b/sys/syscall_pagedir.c
index 33acc87..961c477 100644
--- a/sys/syscall_pagedir.c
+++ b/sys/syscall_pagedir.c
@@ -5,12 +5,13 @@
#include "syscall.h"
static int
-s_syscall_pagedir_map(
+s_get_untyped(
+ lockstack_t *lockstack,
jove_owned_obj_t *objdir,
- jove_owned_obj_t *target_obj,
+ jove_owned_obj_t *pml4,
size_t payload_bytes,
void *payload_data,
- jove_owned_obj_t **untyped_ret)
+ jove_perm_obj_t *untyped_ret)
{
size_t bytes_needed = sizeof(struct syscall_pagedir_map);
CHECK_TOOSMALL(bytes_needed, payload_bytes,
@@ -27,40 +28,44 @@ s_syscall_pagedir_map(
"Message too small for untyped path.");
errno = 0;
- jove_owned_obj_t *untyped_obj = objdir_trygetobj(objdir,
- payload->untyped_path, payload->untyped_pathlen);
+ jove_perm_obj_t untyped = link_try_traverse(
+ lockstack_push(lockstack, objdir_trygetobj(
+ objdir, payload->untyped_path, payload->untyped_pathlen)),
+ lockstack);
if(errno) {
kprintf("%s: Untyped obj failed for the reason: %s\n", __func__, errstr(errno));
return errno;
}
- CHECK_OBJTYPE(untyped_obj, JOVE_OBJ_UNTYPED,
+ CHECK_OBJTYPE(untyped.obj, JOVE_OBJ_UNTYPED,
"Untyped path does not point to an untyped object.");
- jove_untyped_t *untyped_data = obj_deref(untyped_obj);
+ CHECK_OBJPERM(untyped, JOVE_PERM_MUTATE,
+ "Untyped object does not have MUTATE permission.");
+
+ jove_untyped_t *untyped_data = obj_deref(untyped.obj);
if((uintptr_t)untyped_data & 0xFFF) {
kprintf("%s: Untyped object is not page aligned.\n", __func__);
- obj_release(untyped_obj);
return EALIGN;
}
if(untyped_data->limit != 0x1000) {
kprintf("%s: Untyped object is not page sized. (expected 0x1000 got 0x%X)\n", __func__,
untyped_data->limit);
- obj_release(untyped_obj);
return EBADSIZE;
}
- *untyped_ret = untyped_obj;
+ *untyped_ret = untyped;
return 0;
}
static int
s_syscall_pagedir_unmap(
+ lockstack_t *lockstack,
jove_owned_obj_t *objdir,
- jove_owned_obj_t *target_obj,
+ jove_owned_obj_t *pagedir,
size_t payload_bytes,
void *payload_data,
- jove_owned_obj_t **none_ret)
+ jove_perm_obj_t *none_ret)
{
size_t bytes_needed = sizeof(struct syscall_pagedir_unmap);
CHECK_TOOSMALL(bytes_needed, payload_bytes,
@@ -76,117 +81,186 @@ s_syscall_pagedir_unmap(
CHECK_TOOSMALL(bytes_needed, payload_bytes,
"Message too small for none path");
- jove_owned_obj_t *none_obj = objdir_trygetobj(objdir,
- payload->none_path, payload->none_pathlen);
+ jove_perm_obj_t none = link_try_traverse(
+ lockstack_push(lockstack, objdir_trygetobj(
+ objdir, payload->none_path, payload->none_pathlen)),
+ lockstack);
if(errno) {
kprintf("%s: None obj retrieval failed for the reason: %s\n",
__func__, errstr(errno));
return errno;
}
- CHECK_OBJTYPE(none_obj, JOVE_OBJ_NONE,
+ CHECK_OBJTYPE(none.obj, JOVE_OBJ_NONE,
"None path does not point to none object.");
- *none_ret = none_obj;
+ *none_ret = none;
return 0;
}
static int
s_syscall_pagedir_map_frame(
+ lockstack_t *lockstack,
jove_owned_obj_t *objdir,
- jove_owned_obj_t *target_obj,
+ jove_owned_obj_t *pagedir,
size_t payload_bytes,
void *payload_data)
{
- jove_owned_obj_t *untyped_obj = NULL;
- int sysret = s_syscall_pagedir_map(objdir, target_obj, payload_bytes, payload_data, &untyped_obj);
+ jove_perm_obj_t untyped = { .obj = NULL, .permissions = 0 };
+ int sysret = s_get_untyped(lockstack, objdir, pagedir, payload_bytes, payload_data, &untyped);
if(sysret != 0) {
return sysret;
}
struct syscall_pagedir_map *payload = payload_data;
- sysret = pagedir_map_untyped_frame(target_obj, untyped_obj, payload->virtual_address, payload->flags);
+ sysret = pagedir_map_untyped_frame(pagedir, &untyped, payload->virtual_address, payload->page_flags);
if(sysret == 0)
- obj_settype(untyped_obj, JOVE_OBJ_NONE);
+ obj_settype(untyped.obj, JOVE_OBJ_NONE);
- obj_release(untyped_obj);
return sysret;
}
static int
s_syscall_pagedir_map_table(
+ lockstack_t *lockstack,
jove_owned_obj_t *objdir,
- jove_owned_obj_t *target_obj,
+ jove_owned_obj_t *pagedir,
size_t payload_bytes,
void *payload_data)
{
- jove_owned_obj_t *untyped_obj = NULL;
- int sysret = s_syscall_pagedir_map(objdir, target_obj, payload_bytes, payload_data, &untyped_obj);
+ jove_perm_obj_t untyped = { .obj = NULL, .permissions = 0 };
+ int sysret = s_get_untyped(lockstack, objdir, pagedir, payload_bytes, payload_data, &untyped);
if(sysret != 0) {
return sysret;
}
struct syscall_pagedir_map *payload = payload_data;
- sysret = pagedir_map_untyped_table(target_obj, untyped_obj, payload->virtual_address);
+ sysret = pagedir_map_untyped_table(pagedir, &untyped, payload->virtual_address);
if(sysret == 0)
- obj_settype(untyped_obj, JOVE_OBJ_NONE);
+ obj_settype(untyped.obj, JOVE_OBJ_NONE);
- obj_release(untyped_obj);
return sysret;
}
static int
+s_syscall_pagedir_map_shmem(
+ lockstack_t *lockstack,
+ jove_owned_obj_t *objdir,
+ jove_owned_obj_t *pagedir,
+ size_t payload_bytes,
+ void *payload_data)
+{
+ size_t bytes_needed = sizeof(struct syscall_pagedir_map_shmem);
+ CHECK_TOOSMALL(bytes_needed, payload_bytes,
+ "Message too small for payload.");
+
+ struct syscall_pagedir_map_shmem *payload = payload_data;
+ if(payload->virtual_address > 0xFFFF800000000000ULL) {
+ kprintf("%s: Virtual address is above user limit.\n", __func__);
+ return EBADARG;
+ }
+
+ bytes_needed += payload->shmem_pathlen << 1;
+ CHECK_TOOSMALL(bytes_needed, payload_bytes,
+ "Message too small for untyped path.");
+
+ errno = 0;
+ jove_perm_obj_t shmem = link_try_traverse(
+ lockstack_push(lockstack, objdir_trygetobj(
+ objdir, payload->shmem_path, payload->shmem_pathlen)),
+ lockstack);
+ if(errno) {
+ klogf("Shared memory obj failed for the reason: %s\n", errstr(errno));
+ return errno;
+ }
+
+ CHECK_OBJTYPE(shmem.obj, JOVE_OBJ_SHMEMORY,
+ "Shared memory path does not point to a shared memory object.");
+
+ uintmax_t shmem_value = obj_getvalue(shmem.obj);
+ uint8_t shmem_pages = shmem_value & 0xFF;
+
+ if(payload->page_offset >= shmem_pages) {
+ klogf("Page offset goes beyond size of shared memory object: (%i >= %i)\n",
+ payload->page_offset, shmem_pages);
+ return -EOOB;
+ }
+
+ return pagedir_map_shmem_frame(pagedir, &shmem, payload->page_offset,
+ payload->virtual_address, payload->page_flags);
+}
+
+static int
s_syscall_pagedir_unmap_frame(
+ lockstack_t *lockstack,
jove_owned_obj_t *objdir,
- jove_owned_obj_t *target_obj,
+ jove_owned_obj_t *pagedir,
size_t payload_bytes,
void *payload_data)
{
- jove_owned_obj_t *none_obj;
- int sysret = s_syscall_pagedir_unmap(objdir, target_obj, payload_bytes, payload_data, &none_obj);
+ jove_perm_obj_t none;
+ int sysret = s_syscall_pagedir_unmap(lockstack, objdir, pagedir, payload_bytes, payload_data, &none);
if(!sysret) return sysret;
struct syscall_pagedir_unmap *payload = payload_data;
- return pagedir_unmap_untyped_frame(target_obj, none_obj, payload->virtual_address);
+ return pagedir_unmap_untyped_frame(pagedir, none.obj, payload->virtual_address);
}
static int
s_syscall_pagedir_unmap_table(
+ lockstack_t *lockstack,
jove_owned_obj_t *objdir,
- jove_owned_obj_t *target_obj,
+ jove_owned_obj_t *pagedir,
size_t payload_bytes,
void *payload_data)
{
- jove_owned_obj_t *none_obj;
- int sysret = s_syscall_pagedir_unmap(objdir, target_obj, payload_bytes, payload_data, &none_obj);
+ jove_perm_obj_t none;
+ int sysret = s_syscall_pagedir_unmap(lockstack, objdir, pagedir, payload_bytes, payload_data, &none);
if(!sysret) return sysret;
struct syscall_pagedir_unmap *payload = payload_data;
- return pagedir_unmap_untyped_table(target_obj, none_obj, payload->virtual_address);
+ return pagedir_unmap_untyped_table(pagedir, none.obj, payload->virtual_address);
}
int
-_syscall_handle_pagedir(
- jove_owned_obj_t *pcb_obj,
- jove_owned_obj_t *objdir,
- jove_owned_obj_t *message_obj,
- jove_owned_obj_t *target_obj,
- struct syscall_header *header,
- size_t bytes_left,
- void *payload)
+_syscall_handle_pagedir(syscall_context_t *ctx)
{
+ lockstack_t *lockstack = &ctx->lockstack;
+ struct syscall_header *header = ctx->header;
+ jove_owned_obj_t *objdir = ctx->objdir;
+ jove_perm_obj_t *target = &ctx->target;
+ size_t bytes_left = ctx->bytes_left;
+ void *payload = ctx->payload;
+
switch(header->callid) {
case SYSCALL_PAGEDIR_MAP_FRAME:
- return s_syscall_pagedir_map_frame(objdir, target_obj, bytes_left, payload);
+ if(target->permissions & SYSCALL_PERM_PAGEDIR_MAP_FRAME)
+ return s_syscall_pagedir_map_frame(lockstack, objdir, target->obj, bytes_left, payload);
+ return -EPERM;
+
case SYSCALL_PAGEDIR_MAP_TABLE:
- return s_syscall_pagedir_map_table(objdir, target_obj, bytes_left, payload);
+ if(target->permissions & SYSCALL_PERM_PAGEDIR_MAP_TABLE)
+ return s_syscall_pagedir_map_table(lockstack, objdir, target->obj, bytes_left, payload);
+ return -EPERM;
+
+ case SYSCALL_PAGEDIR_MAP_SHMEM:
+ if(target->permissions & SYSCALL_PERM_PAGEDIR_MAP_SHMEM)
+ return s_syscall_pagedir_map_shmem(lockstack, objdir, target->obj, bytes_left, payload);
+ return -EPERM;
+
case SYSCALL_PAGEDIR_UNMAP_FRAME:
- return s_syscall_pagedir_unmap_frame(objdir, target_obj, bytes_left, payload);
+ if(target->permissions & SYSCALL_PERM_PAGEDIR_UNMAP_FRAME)
+ return s_syscall_pagedir_unmap_frame(lockstack, objdir, target->obj, bytes_left, payload);
+ return -EPERM;
+
case SYSCALL_PAGEDIR_UNMAP_TABLE:
- return s_syscall_pagedir_unmap_table(objdir, target_obj, bytes_left, payload);
+ if(target->permissions & SYSCALL_PERM_PAGEDIR_UNMAP_TABLE)
+ return s_syscall_pagedir_unmap_table(lockstack, objdir, target->obj, bytes_left, payload);
+ return -EPERM;
+
default:
kprintf("syscall_handle_pagedir: Pagedir does not support syscall %i\n", header->callid);
return EBADARG;
diff --git a/sys/syscall_untyped.c b/sys/syscall_untyped.c
index a5659a6..a117387 100644
--- a/sys/syscall_untyped.c
+++ b/sys/syscall_untyped.c
@@ -6,6 +6,7 @@
static int
s_syscall_untyped_split(
+ lockstack_t *lockstack,
jove_owned_obj_t *objdir,
jove_owned_obj_t *target_obj,
size_t payload_bytes,
@@ -18,19 +19,24 @@ s_syscall_untyped_split(
bytes_needed += payload->dest_pathlen * 2;
CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for destination path!");
- jove_owned_obj_t *dst_obj = objdir_getobj(objdir, payload->dest_path, payload->dest_pathlen);
- CHECK_OBJTYPE(dst_obj, JOVE_OBJ_NONE, "Destination path is occupied!");
+ jove_perm_obj_t dest = link_try_traverse(
+ lockstack_push(lockstack,
+ objdir_trygetobj(objdir, payload->dest_path, payload->dest_pathlen)),
+ lockstack);
+
+ CHECK_OBJTYPE(dest.obj, JOVE_OBJ_NONE, "Destination path is occupied!");
if(payload->bytes < JOVE_UNTYPED_MINSIZE) {
klogf("Destination untyped would be too small. (%X < %X)\n",
payload->bytes, JOVE_UNTYPED_MINSIZE);
- return EBADARG;
+ return -ETOOBIG;
}
- return untyped_split(target_obj, dst_obj, payload->bytes);
+ return untyped_split(target_obj, dest.obj, payload->bytes);
}
static int
s_syscall_untyped_merge(
+ lockstack_t *lockstack,
jove_owned_obj_t *objdir,
jove_owned_obj_t *target_obj,
size_t payload_bytes,
@@ -43,41 +49,51 @@ s_syscall_untyped_merge(
bytes_needed += payload->pathlen * 2;
CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for second path!");
- jove_owned_obj_t *snd_obj = objdir_getobj(objdir, payload->path, payload->pathlen);
- CHECK_OBJTYPE(snd_obj, JOVE_OBJ_UNTYPED, "Second object is not an untyped!");
+ jove_perm_obj_t untyped = link_try_traverse(
+ lockstack_push(lockstack,
+ objdir_getobj(objdir, payload->path, payload->pathlen)),
+ lockstack);
+ CHECK_OBJTYPE(untyped.obj, JOVE_OBJ_UNTYPED, "Second object is not an untyped!");
+ CHECK_OBJPERM(untyped, SYSCALL_PERM_UNTYPED_MERGE, "Second untyped does not have permission to merge!");
- int sysret = untyped_merge(target_obj, snd_obj);
- if(obj_gettype(snd_obj) == JOVE_OBJ_UNTYPED) {
+ int sysret = untyped_merge(target_obj, untyped.obj);
+ if(obj_gettype(untyped.obj) == JOVE_OBJ_UNTYPED) {
//Untyped merged into second object. We need to switch objects.
obj_settype(target_obj, JOVE_OBJ_UNTYPED);
- obj_setvalue(target_obj, obj_getvalue(snd_obj));
- obj_settype(snd_obj, JOVE_OBJ_NONE);
+ obj_setvalue(target_obj, obj_getvalue(untyped.obj));
+ obj_settype(untyped.obj, JOVE_OBJ_NONE);
}
return sysret;
}
-int _syscall_handle_untyped(
- jove_owned_obj_t* pcb_obj,
- jove_owned_obj_t* objdir,
- jove_owned_obj_t* message_obj,
- jove_owned_obj_t* target_obj,
- struct syscall_header* header,
- size_t payload_bytes,
- void* payload)
+int _syscall_handle_untyped(syscall_context_t *ctx)
{
- switch(header->callid) {
- case SYSCALL_UNTYPED_ADDRESS:
- return untyped_address(target_obj);
+ switch(ctx->header->callid) {
+ case SYSCALL_UNTYPED_ADDRESS:
+ if(ctx->target.permissions & SYSCALL_PERM_UNTYPED_ADDRESS)
+ return untyped_address(ctx->target.obj);
+ return -EPERM;
+
case SYSCALL_UNTYPED_SIZE:
- return untyped_size(target_obj);
+ if(ctx->target.permissions & SYSCALL_PERM_UNTYPED_SIZE)
+ return untyped_size(ctx->target.obj);
+ return -EPERM;
+
case SYSCALL_UNTYPED_SPLIT:
- return s_syscall_untyped_split(objdir, target_obj, payload_bytes, payload);
+ if(ctx->target.permissions & SYSCALL_PERM_UNTYPED_SPLIT)
+ return s_syscall_untyped_split(
+ &ctx->lockstack, ctx->objdir, ctx->target.obj, ctx->bytes_left, ctx->payload);
+ return -EPERM;
+
case SYSCALL_UNTYPED_MERGE:
- return s_syscall_untyped_merge(objdir, target_obj, payload_bytes, payload);
+ if(ctx->target.permissions & SYSCALL_PERM_UNTYPED_MERGE)
+ return s_syscall_untyped_merge(
+ &ctx->lockstack, ctx->objdir, ctx->target.obj, ctx->bytes_left, ctx->payload);
+ return -EPERM;
+
default:
- kprintf("syscall_untyped: Untyped object does not support syscall %i\n", header->callid);
- return -EBADARG;
+ return -EBADCALL;
}
return 0;
}
diff --git a/sys/syscall_vtt.c b/sys/syscall_vtt.c
index 4dadd6c..dad05ba 100644
--- a/sys/syscall_vtt.c
+++ b/sys/syscall_vtt.c
@@ -20,20 +20,14 @@ s_syscall_vtt_write(
}
int
-_syscall_handle_vtt(
- jove_owned_obj_t *pcb_obj,
- jove_owned_obj_t *objdir,
- jove_owned_obj_t *message_obj,
- jove_owned_obj_t *target_obj,
- struct syscall_header *header,
- size_t bytes_left,
- void *payload_data)
+_syscall_handle_vtt(syscall_context_t *ctx)
{
- switch(header->callid) {
- case 0:
- return s_syscall_vtt_write(target_obj, bytes_left, payload_data);
+
+ switch(ctx->header->callid) {
+ case SYSCALL_VTT_WRITE:
+ return s_syscall_vtt_write(ctx->target.obj, ctx->bytes_left, ctx->payload);
default:
- kprintf("syscall_vtt: vtt object does not support syscall %i\n", header->callid);
- return EOOB;
+ klogf("vtt object does not support syscall %i\n", ctx->header->callid);
+ return -EBADCALL;
}
}