summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-10-03 21:32:29 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-10-03 21:32:29 -0400
commit465cba0c00bfc5d89bf10ce353b0adf40bdc098d (patch)
tree914fd856946800199e2191dda1659ba9ccd55978 /sys
parent153ac5fa0b8c4d178bf7590f0344612c6c3eaa70 (diff)
downloadjove-kernel-465cba0c00bfc5d89bf10ce353b0adf40bdc098d.tar.gz
jove-kernel-465cba0c00bfc5d89bf10ce353b0adf40bdc098d.tar.bz2
jove-kernel-465cba0c00bfc5d89bf10ce353b0adf40bdc098d.zip
unmap message object used for syscalls
Diffstat (limited to 'sys')
-rw-r--r--sys/message.c53
-rw-r--r--sys/message.h10
-rw-r--r--sys/syscall.c50
-rw-r--r--sys/syscall_initrd_file.c17
-rw-r--r--sys/syscall_message.c4
5 files changed, 94 insertions, 40 deletions
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;
}