diff options
| author | Jon Santmyer <jon@jonsantmyer.com> | 2026-09-12 22:00:09 -0400 |
|---|---|---|
| committer | Jon Santmyer <jon@jonsantmyer.com> | 2026-09-12 22:00:09 -0400 |
| commit | 53fa3cd2bfdb122d773024612d8c1d71f0dd8188 (patch) | |
| tree | 5ffe81718b400031ca9b3b68a6d152c574270af2 /sys/syscall.c | |
| parent | 1d1a5cde7de28752727e3d56305a74afac8848ff (diff) | |
| download | jove-kernel-53fa3cd2bfdb122d773024612d8c1d71f0dd8188.tar.gz jove-kernel-53fa3cd2bfdb122d773024612d8c1d71f0dd8188.tar.bz2 jove-kernel-53fa3cd2bfdb122d773024612d8c1d71f0dd8188.zip | |
add paging support
Diffstat (limited to 'sys/syscall.c')
| -rw-r--r-- | sys/syscall.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/sys/syscall.c b/sys/syscall.c index 9a98030..eb2874d 100644 --- a/sys/syscall.c +++ b/sys/syscall.c @@ -7,6 +7,22 @@ #include "sys/link.h" #include "sys/message.h" +int __syscall_generic_objpath(jove_owned_obj_t *objdir, size_t payload_bytes, void *payload_data, jove_owned_obj_t **retobj) +{ + size_t bytes_needed = sizeof(struct syscall_generic_objpath); + CHECK_TOOSMALL(bytes_needed, payload_bytes, + "Message too small for payload."); + struct syscall_generic_objpath *payload = payload_data; + + bytes_needed += payload->pathlen << 1; + CHECK_TOOSMALL(bytes_needed, payload_bytes, + "Message too small for object path."); + + errno = 0; + *retobj = objdir_getobj(objdir, payload->path, payload->pathlen); + return errno; +} + int _syscall_handle_generic( jove_owned_obj_t *pcb_obj, @@ -47,17 +63,15 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) 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_getobj(objdir, message_path, message_pathlen); + + int sysret = 0; if(message_obj == 0) { - obj_release(objdir); - obj_release(pcb_obj); - return errno; + sysret = errno; + goto release_premsg; } - int sysret = 0; if(obj_gettype_linked(message_obj) != JOVE_OBJ_MESSAGE) { kprintf("syscall: Process %i tried to call syscall with invalid object: %P\n", pcb_pid(pcb), message_path, message_pathlen); sysret = EBADOBJ; @@ -68,12 +82,11 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) void *messagedata = message_data(message_obj); struct syscall_header *header = messagedata; - size_t header_bytes = sizeof(struct syscall_header) + header->pathlen * 2; - int bytes_left = messagelen - header_bytes; - if(bytes_left < 0) { + size_t bytes_needed = sizeof(struct syscall_header) + header->pathlen * 2; + if(bytes_needed > messagelen) { //Target path exceeds message length. - kprintf("syscall: Process %i tried to call syscall with OOB target path.\n", pcb_pid(pcb)); - sysret = EBADPATH; + kprintf("syscall: Process %i tried to call syscall with target path too big for message.\n", pcb_pid(pcb)); + sysret = ETOOSMALL; goto release_return; } jove_owned_obj_t *target = objdir_getobj(objdir, header->path, header->pathlen); @@ -86,10 +99,11 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) } 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 + header_bytes); + header, bytes_left, messagedata + bytes_needed); }else{ syscall_handle_t call_handle = s_syscall_handles[obj_gettype(target)]; if(call_handle == NULL) { @@ -99,11 +113,12 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) }else sysret = call_handle( pcb_obj, objdir, message_obj, target, - header, bytes_left, messagedata + header_bytes); + header, bytes_left, messagedata + bytes_needed); } obj_release(target); release_return: obj_release(message_obj); +release_premsg: obj_release(objdir); obj_release(pcb_obj); return sysret; |
