diff options
Diffstat (limited to 'sys/syscall_untyped.c')
| -rw-r--r-- | sys/syscall_untyped.c | 68 |
1 files changed, 42 insertions, 26 deletions
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; } |
