diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm index dba9bf8e..1a37ceea 100644 --- a/kernel-src/arch/x86-64/syscall.asm +++ b/kernel-src/arch/x86-64/syscall.asm @@ -82,6 +82,7 @@ extern syscall_getresuid extern syscall_getresgid extern syscall_setresuid extern syscall_setresgid +extern syscall_mprotect syscalltab: dq syscall_print dq syscall_mmap @@ -166,7 +167,8 @@ dq syscall_getresuid dq syscall_getresgid dq syscall_setresuid dq syscall_setresgid -syscallcount equ 83 +dq syscall_mprotect +syscallcount equ 84 section .text global arch_syscall_entry ; on entry: diff --git a/kernel-src/arch/x86-64/syscalllog.c b/kernel-src/arch/x86-64/syscalllog.c index 2526f177..e37132ca 100644 --- a/kernel-src/arch/x86-64/syscalllog.c +++ b/kernel-src/arch/x86-64/syscalllog.c @@ -5,7 +5,7 @@ #ifdef SYSCALL_LOGGING -#define SYSCALL_COUNT 83 +#define SYSCALL_COUNT 84 #define LOGSTR(x) arch_e9_puts(x) static char *name[] = { @@ -91,7 +91,8 @@ static char *name[] = { "getresuid", "getresgid", "setresuid", - "setresgid" + "setresgid", + "mprotect" }; static char *args[] = { @@ -177,7 +178,8 @@ static char *args[] = { "uidp %p euidp %p suidp %p", // getresuid "gidp %p egidp %p sgidp %p", // getresgid "uid %d euid %d suid %d", // setresuid - "gid %d egid %d sgid %d" // setresgid + "gid %d egid %d sgid %d", // setresgid + "addr %p len %lu prot %d" // mprotect }; #endif diff --git a/kernel-src/sys/syscalls/mprotect.c b/kernel-src/sys/syscalls/mprotect.c new file mode 100644 index 00000000..bc26c80e --- /dev/null +++ b/kernel-src/sys/syscalls/mprotect.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +#define PROT_READ 0x01 +#define PROT_WRITE 0x02 +#define PROT_EXEC 0x04 + +#define KNOWN_PROT (PROT_READ | PROT_WRITE | PROT_EXEC) + +syscallret_t syscall_mprotect(context_t *context, void *address, size_t len, int prot) { + syscallret_t ret = { + .errno = 0, + .ret = -1 + }; + + __assert((~KNOWN_PROT & prot) == 0); + + // check alignment + if (len == 0 || (uintptr_t)address % PAGE_SIZE || address > USERSPACE_END) { + ret.errno = EINVAL; + return ret; + } + + mmuflags_t mmuflags = ARCH_MMU_FLAGS_USER; + if (prot & PROT_READ) + mmuflags |= ARCH_MMU_FLAGS_READ; + if (prot & PROT_WRITE) + mmuflags |= ARCH_MMU_FLAGS_WRITE; + if ((prot & PROT_EXEC) == 0) + mmuflags |= ARCH_MMU_FLAGS_NOEXEC; + + ret.errno = vmm_changemmuflags(address, len, mmuflags, 0) ? 0 : ENOMEM; + ret.ret = ret.errno ? -1 : 0; + + return ret; +} diff --git a/patches/mlibc/jinx-working-patch.patch b/patches/mlibc/jinx-working-patch.patch index 859c0510..bdbf7c1b 100644 --- a/patches/mlibc/jinx-working-patch.patch +++ b/patches/mlibc/jinx-working-patch.patch @@ -207,10 +207,10 @@ index 0000000..e5b087a + diff --git mlibc-workdir/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp new file mode 100644 -index 0000000..cfb7dfd +index 0000000..e58c9ac --- /dev/null +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp -@@ -0,0 +1,970 @@ +@@ -0,0 +1,975 @@ +#include +#include +#include @@ -279,6 +279,11 @@ index 0000000..cfb7dfd + return 0; + } + ++ int sys_vm_protect(void *pointer, size_t size, int prot) { ++ long ret; ++ return syscall(SYSCALL_MPROTECT, &ret, (uint64_t)pointer, size, prot); ++ } ++ + int sys_setuid(uid_t id) { + return sys_setresuid(id, -1, -1); + } @@ -1200,10 +1205,10 @@ index 0000000..990eca0 +#endif diff --git mlibc-workdir/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h new file mode 100644 -index 0000000..6db5755 +index 0000000..4d30885 --- /dev/null +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h -@@ -0,0 +1,106 @@ +@@ -0,0 +1,107 @@ +#ifndef _SYSCALL_H_INCLUDE +#define _SYSCALL_H_INCLUDE + @@ -1290,6 +1295,7 @@ index 0000000..6db5755 +#define SYSCALL_GETRESGID 80 +#define SYSCALL_SETRESUID 81 +#define SYSCALL_SETRESGID 82 ++#define SYSCALL_MPROTECT 83 + +#include +#include