From 5f813d49a08cf3c3f8cf6c422cfb6587df575f62 Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Sat, 26 Sep 2026 17:11:50 -0400 Subject: add docs for syscalls. make syscall code kind-of cleaner --- sys/link.c | 56 ++++++++++++----- sys/link.h | 24 +++++-- sys/lockstack.c | 30 +++++++++ sys/lockstack.h | 18 ++++++ sys/syscall.c | 105 ++++++++++++++++--------------- sys/syscall.h | 45 ++++++++----- sys/syscall_objdir.c | 19 +++--- sys/syscall_pagedir.c | 170 ++++++++++++++++++++++++++++++++++++-------------- sys/syscall_untyped.c | 68 ++++++++++++-------- sys/syscall_vtt.c | 20 +++--- 10 files changed, 368 insertions(+), 187 deletions(-) create mode 100644 sys/lockstack.c create mode 100644 sys/lockstack.h (limited to 'sys') 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 +#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, @@ -54,37 +46,64 @@ static const syscall_handle_t s_syscall_handles[128] = { [JOVE_OBJ_LINK] = _syscall_handle_generic, }; +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 #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; } } -- cgit v1.2.3