From 2497a94013261d6fa9159b9c6e94abe6f2d4fd9e Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Sat, 3 Oct 2026 12:03:11 -0400 Subject: process rbtree. add syscall for initrd_file access. --- sys/syscall_initrd_file.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 sys/syscall_initrd_file.c (limited to 'sys/syscall_initrd_file.c') diff --git a/sys/syscall_initrd_file.c b/sys/syscall_initrd_file.c new file mode 100644 index 0000000..8e34488 --- /dev/null +++ b/sys/syscall_initrd_file.c @@ -0,0 +1,98 @@ +#include "api/error.h" +#include "boot/initrd.h" +#include "lib/printf.h" +#include "sys/message.h" +#include "sys/syscall.h" +#include "lib/string.h" + +int +s_syscall_initrd_file_name( + jove_owned_obj_t *initrd_file, + jove_owned_obj_t *message) +{ + const char *filename = initrd_file_name(initrd_file); + size_t filename_len = strlen(filename); + + size_t bytes_left = message_len(message); + 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); + + payload->len = filename_len; + memcpy(payload->c_str, filename, filename_len); + return 0; +} + +int +s_syscall_initrd_file_size(jove_owned_obj_t *initrd_file) +{ + return initrd_file_size(initrd_file); +} + +int +s_syscall_initrd_file_read( + jove_owned_obj_t *initrd_file, + jove_owned_obj_t *message, + size_t bytes_left, + void *payload_data) +{ + //Ensure that the message payload could hold the required read payload. + size_t bytes_needed = sizeof(struct syscall_initrd_file_read); + CHECK_TOOSMALL(bytes_needed, bytes_left, + "Message is too small to hold read payload."); + + struct syscall_initrd_file_read *payload = payload_data; + bytes_needed = payload->read_size; + bytes_left = message_len(message); + + //Ensure that the message is big enough to hold the read file data. + CHECK_TOOSMALL(bytes_needed, bytes_left, + "Message is too small to hold read bytes."); + + size_t file_size = initrd_file_size(initrd_file); + char *file_data = initrd_file_data(initrd_file); + + //Ensure that the start index is within the file. + if(payload->start_index >= file_size) { + klogf("Start index exceeds file length! (%i > %i)\n", + payload->start_index, file_size); + return -EOOB; + } + + //Ensure that the read bounds is within the file. + if(payload->start_index + payload->read_size > file_size) { + klogf("Read bounds exceed file length! (%i+%i > %i)\n", + payload->start_index, payload->read_size, file_size); + return -ETOOBIG; + } + + void *read_data = message_data(message); + memcpy(read_data, file_data + payload->start_index, payload->read_size); + return 0; +} + +int +_syscall_handle_initrd_file(syscall_context_t *ctx) +{ + switch(ctx->header->callid) { + 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); + return -EPERM; + + case SYSCALL_INITRD_FILE_SIZE: + if(ctx->target.permissions & SYSCALL_PERM_INITRD_FILE_SIZE) + return s_syscall_initrd_file_size(ctx->target.obj); + return -EPERM; + + 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); + return -EPERM; + default: + return -EBADCALL; + } +} -- cgit v1.2.3