From f601c99d399dab981e52417947a4de111dba741f Mon Sep 17 00:00:00 2001 From: Andreew Gregory Date: Mon, 6 Apr 2026 05:41:34 +0300 Subject: [PATCH] chatgpt solved this one for me --- cpu/idt.c | 53 ++++++++++++++++++++++++++++++++++++++++++---------- proc.c | 3 +++ user/snake.c | 8 ++++++++ 3 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 user/snake.c diff --git a/cpu/idt.c b/cpu/idt.c index e742efd..cf804bf 100644 --- a/cpu/idt.c +++ b/cpu/idt.c @@ -118,17 +118,44 @@ void trap(registers_t *r) { } /* takes a ptr that is supposed to be from userspace. If it is not, we - * return 0, if it is a valid userspace pointer, we return the usable - * kernelspace pointer + * return 0, if it is a valid we return 1 */ -uint32_t is_userspace_ptr_mapped(uint32_t ptr) { - // todo: implement - return ptr; +bool is_userspace_ptr_mapped(uint32_t ptr) { + if (ptr >= KERNBASE) { + return 0; + } + + pde_t *pgdir = get_user_proc_page_directory(); + if (!pgdir) { + return 0; + } + + pde_t pde = pgdir[PDX(ptr)]; + if ((pde & (PTE_P | PTE_U)) != (PTE_P | PTE_U)) { + return 0; + } + if (pde & PDE_PS) { + return 0; + } + + pte_t *table = (pte_t*)P2V(PTE_ADDR(pde)); + pte_t pte = table[PTX(ptr)]; + if ((pte & (PTE_P | PTE_U)) != (PTE_P | PTE_U)) { + return 0; + } + + return 1; } static void* get_userspace_cstr(uint32_t ptr) { - // todo: implement - return (void*)(ptr); + for (uint32_t addr = ptr;; addr++) { + if (addr == 0 || !is_userspace_ptr_mapped(addr)) { + return 0; + } + if (*(const char*)addr == '\0') { + return (void*)ptr; + } + } } static int handle_puts(const char* s) { @@ -140,6 +167,7 @@ static int handle_puts(const char* s) { } static void handle_syscall(registers_t* r) { + int ret; switch (r->eax) { case SYS_exit: if (r->ebx == 0) { @@ -157,11 +185,16 @@ static void handle_syscall(registers_t* r) { r->eax = 0; break; case SYS_puts: - r->eax = handle_puts(get_userspace_cstr(r->ebx)); + ret = handle_puts(get_userspace_cstr(r->ebx)); + if (ret < 0) { + printk("SYS_puts panic: page fault\n"); + killproc(); + } + r->eax = 0; break; default: - printk("Unknown syscall\n"); - r->eax = -1; + printk("Userspace panic: Unknown syscall\n"); + killproc(); } } diff --git a/proc.c b/proc.c index a8730b8..8bc0a58 100644 --- a/proc.c +++ b/proc.c @@ -28,6 +28,9 @@ void trapret(); void swtch(void** oldstack, void* newstack); pde_t *get_user_proc_page_directory() { + // if (!vm.user_task) { + // return 0; + // } return vm.user_task->pgdir; } diff --git a/user/snake.c b/user/snake.c new file mode 100644 index 0000000..7a3057f --- /dev/null +++ b/user/snake.c @@ -0,0 +1,8 @@ +#include "../syscall.h" +#include +#include + +int main() { + return 0; + +}