From 465cba0c00bfc5d89bf10ce353b0adf40bdc098d Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Sat, 3 Oct 2026 21:32:29 -0400 Subject: unmap message object used for syscalls --- sys/message.c | 53 ++++++++++++++++++++++++++++++++++++++++------- sys/message.h | 10 +++++---- sys/syscall.c | 50 +++++++++++++++++++++++++++++--------------- sys/syscall_initrd_file.c | 17 ++++++++------- sys/syscall_message.c | 4 ---- 5 files changed, 94 insertions(+), 40 deletions(-) (limited to 'sys') diff --git a/sys/message.c b/sys/message.c index 7c871ce..c87487b 100644 --- a/sys/message.c +++ b/sys/message.c @@ -1,15 +1,54 @@ #include "message.h" +#include "api/error.h" +#include "errno.h" +#include "hal/memory.h" #include "hal/obj.h" +#include "lib/printf.h" -void * -message_data(jove_owned_obj_t *obj) +int +message_hasmap(jove_owned_obj_t *obj) { - uintptr_t objptr = (uintptr_t)obj_deref(obj); - return (void*)(objptr & ~0xFFF); + return obj_getvalue(obj) & 1; } -size_t -message_len(jove_owned_obj_t *obj) +uintptr_t +message_unmap(jove_owned_obj_t *obj, jove_owned_obj_t *pagedir) { - return (obj_getvalue(obj) & 0xFFF) << 12; + if(message_hasmap(obj) == 0) { + kprintf("Message %p doesn't have a map\n", obj_getvalue(obj)); + return -ENOMAP; + } + uintptr_t vptr = obj->locked.value & ~0xFFFULL; + uintptr_t *mapping = pagedir_get_mapping(pagedir, vptr); + + pagedir_mapping_set_present(mapping, false); + pagedir_invlpg(vptr); + + obj_setvalue(obj, *mapping); + return vptr; +} + +void +message_remap(jove_owned_obj_t *message, jove_owned_obj_t *pagedir, uintptr_t vptr) +{ + if(message_hasmap(message)) { + errno = -EHASMAP; + return; + } + + uintmax_t *mapping = pagedir_get_mapping(pagedir, vptr); + + *mapping = obj_getvalue(message) | 1; + pagedir_invlpg(vptr); + + obj_setvalue(message, vptr | 1); +} + +uintptr_t message_getdata(jove_owned_obj_t *message) +{ + if(message_hasmap(message)) + return obj_getvalue(message) & ~0xFFFULL; + + uintptr_t message_val = obj_getvalue(message); + return pagedir_ident_from_mapping(&message_val); } diff --git a/sys/message.h b/sys/message.h index 2ae6e03..97d0f71 100644 --- a/sys/message.h +++ b/sys/message.h @@ -3,11 +3,13 @@ #include "hal/obj.h" -#define MESSAGE_MAX_PAGES (1<<12) -#define MESSAGE_MAX_BYTES (MESSAGE_MAX_PAGES * 0x1000) + #define MESSAGE_ALIGN 0x1000 -void *message_data(jove_owned_obj_t *obj); -size_t message_len(jove_owned_obj_t *obj); +int message_hasmap(jove_owned_obj_t *message); +uintptr_t message_unmap(jove_owned_obj_t *message, jove_owned_obj_t *pagedir); +void message_remap(jove_owned_obj_t *message, jove_owned_obj_t *pagedir, uintptr_t vptr); + +uintptr_t message_getdata(jove_owned_obj_t *message); #endif diff --git a/sys/syscall.c b/sys/syscall.c index 1c9af45..7207708 100644 --- a/sys/syscall.c +++ b/sys/syscall.c @@ -1,5 +1,6 @@ #include "sys/syscall.h" #include "arch/x86_64/hal/obj.h" +#include "hal/memory.h" #include "hal/smp.h" #include "proc/process.h" #include "jove.h" @@ -27,7 +28,7 @@ int _syscall_handle_generic(syscall_context_t *ctx) { 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); + klogf("Process %i encountered stub syscall on object %P\n", pcb_getpid(pcb), ctx->header->path, ctx->header->pathlen); return -EBADOBJ; } @@ -92,35 +93,38 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) if(ctx.message.obj == NULL) { klogf("Process %i failed to get message %P : %s\n", - pcb_pid(pcb), message_path, message_pathlen, errstr(errno)); + pcb_getpid(pcb), message_path, message_pathlen, errstr(errno)); sysret = -errno; goto release_return; } 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); + pcb_getpid(pcb), message_path, message_pathlen); sysret = -EBADOBJ; goto release_return; } if((ctx.message.permissions & JOVE_PERM_READ) == 0) { klogf("Process %i tried to call syscall with message object %P without read permissions\n", - pcb_pid(pcb), message_path, message_pathlen); + pcb_getpid(pcb), message_path, message_pathlen); sysret = -EPERM; goto release_return; } - size_t messagelen = message_len(ctx.message.obj); - void *messagedata = message_data(ctx.message.obj); + uintptr_t message_vptr = message_unmap(ctx.message.obj, + (jove_owned_obj_t*)pcb_pagedir(pcb)); + + size_t messagelen = 0x1000; + void *messagedata = (void*)message_getdata(ctx.message.obj); struct syscall_header *header = messagedata; size_t bytes_needed = sizeof(struct syscall_header) + header->pathlen * 2; if(bytes_needed > messagelen) { //Target path exceeds message length. - klogf("Process %i tried to call syscall with target path too big for message.\n", pcb_pid(pcb)); + klogf("Process %i tried to call syscall with target path too big for message.\n", pcb_getpid(pcb)); sysret = -ETOOSMALL; - goto release_return; + goto remap_return; } ctx.header = header; @@ -128,17 +132,29 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) ctx.payload = (void*)((uintptr_t)header + bytes_needed); ctx.target = link_try_traverse_objdir( - ctx.objdir, &ctx.lockstack, ctx.header->pathlen, ctx.header->path); - - 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)); - sysret = -errno; - goto release_return; + ctx.objdir, &ctx.lockstack, ctx.header->pathlen, ctx.header->path); + + if(ctx.target.obj != 0) { + sysret = _syscall_handle_switch(&ctx); + }else{ + //Check if we're trying to reference the PCB. If we are, we should set it as the target + //regardless of lock. + if(ctx.header->pathlen == 1 && + objdir_peeklocal(ctx.objdir, ctx.header->path[0]).data == ctx.pcb->locked.data) + { + ctx.target = (jove_perm_obj_t) { .permissions = 0xFF, .obj = ctx.pcb }; + sysret = _syscall_handle_switch(&ctx); + + }else{ + //Could not find payload target in pcb rootdir. + klogf("Process %i tried to call syscall with bad target path %P : %s\n", + pcb_getpid(pcb), header->path, header->pathlen, errstr(errno)); + sysret = -errno; + } } - sysret = _syscall_handle_switch(&ctx); +remap_return: + message_remap(ctx.message.obj, (jove_owned_obj_t*)pcb_pagedir(pcb), message_vptr); release_return: lockstack_popall(&ctx.lockstack); diff --git a/sys/syscall_initrd_file.c b/sys/syscall_initrd_file.c index 8e34488..904039d 100644 --- a/sys/syscall_initrd_file.c +++ b/sys/syscall_initrd_file.c @@ -8,16 +8,17 @@ int s_syscall_initrd_file_name( jove_owned_obj_t *initrd_file, - jove_owned_obj_t *message) + jove_owned_obj_t *message, + void *message_data) { const char *filename = initrd_file_name(initrd_file); size_t filename_len = strlen(filename); - size_t bytes_left = message_len(message); + size_t bytes_left = 0x1000; size_t bytes_needed = filename_len + sizeof(struct syscall_initrd_file_name_ret); CHECK_TOOSMALL(bytes_needed, bytes_left, "Message is too small for file name."); - struct syscall_initrd_file_name_ret *payload = message_data(message); + struct syscall_initrd_file_name_ret *payload = message_data; payload->len = filename_len; memcpy(payload->c_str, filename, filename_len); @@ -34,6 +35,7 @@ int s_syscall_initrd_file_read( jove_owned_obj_t *initrd_file, jove_owned_obj_t *message, + void *message_data, size_t bytes_left, void *payload_data) { @@ -44,7 +46,7 @@ s_syscall_initrd_file_read( struct syscall_initrd_file_read *payload = payload_data; bytes_needed = payload->read_size; - bytes_left = message_len(message); + bytes_left = 0x1000; //Ensure that the message is big enough to hold the read file data. CHECK_TOOSMALL(bytes_needed, bytes_left, @@ -67,8 +69,7 @@ s_syscall_initrd_file_read( return -ETOOBIG; } - void *read_data = message_data(message); - memcpy(read_data, file_data + payload->start_index, payload->read_size); + memcpy(message_data, file_data + payload->start_index, payload->read_size); return 0; } @@ -79,7 +80,7 @@ _syscall_handle_initrd_file(syscall_context_t *ctx) case SYSCALL_INITRD_FILE_NAME: if(ctx->target.permissions & SYSCALL_PERM_INITRD_FILE_NAME) return s_syscall_initrd_file_name( - ctx->target.obj, ctx->message.obj); + ctx->target.obj, ctx->message.obj, (void*)ctx->header); return -EPERM; case SYSCALL_INITRD_FILE_SIZE: @@ -90,7 +91,7 @@ _syscall_handle_initrd_file(syscall_context_t *ctx) case SYSCALL_INITRD_FILE_READ: if(ctx->target.permissions & SYSCALL_PERM_INITRD_FILE_READ) return s_syscall_initrd_file_read( - ctx->target.obj, ctx->message.obj, ctx->bytes_left, ctx->payload); + ctx->target.obj, ctx->message.obj, (void*)ctx->header, ctx->bytes_left, ctx->payload); return -EPERM; default: return -EBADCALL; diff --git a/sys/syscall_message.c b/sys/syscall_message.c index 5edf33f..6c5fb8f 100644 --- a/sys/syscall_message.c +++ b/sys/syscall_message.c @@ -6,10 +6,6 @@ int _syscall_handle_message(syscall_context_t *ctx) { switch(ctx->header->callid) { - case SYSCALL_OBJDIR_OBJTYPE: - if(ctx->target.permissions & SYSCALL_PERM_OBJDIR_OBJTYPE) - return message_len(ctx->message.obj); - return -EPERM; default: return -EBADCALL; } -- cgit v1.2.3