From 1c4f1ab86725af0619f1dc248bc38901be71b114 Mon Sep 17 00:00:00 2001 From: apio Date: Fri, 28 Oct 2022 17:19:26 +0200 Subject: [PATCH] Kernel, libc: Add setuid() and setgid() system calls --- kernel/include/sys/Syscall.h | 6 ++++- kernel/src/sys/Syscall.cpp | 2 ++ kernel/src/sys/id.cpp | 48 +++++++++++++++++++++++++++++++++ libs/libc/include/sys/syscall.h | 2 ++ libs/libc/src/syscall.cpp | 2 ++ 5 files changed, 59 insertions(+), 1 deletion(-) diff --git a/kernel/include/sys/Syscall.h b/kernel/include/sys/Syscall.h index cc40242c..036eba79 100644 --- a/kernel/include/sys/Syscall.h +++ b/kernel/include/sys/Syscall.h @@ -28,6 +28,8 @@ #define SYS_getdents 22 #define SYS_stat 23 #define SYS_dup2 24 +#define SYS_setuid 25 +#define SYS_setgid 26 struct stat; struct pstat; @@ -62,4 +64,6 @@ void sys_fstat(Context* context, int fd, struct stat* buf); void sys_pstat(Context* context, long pid, struct pstat* buf); void sys_getdents(Context* context, int fd, struct luna_dirent* buf, size_t count); void sys_stat(Context* context, const char* path, struct stat* buf); -void sys_dup2(Context* context, int fd, int fd2); \ No newline at end of file +void sys_dup2(Context* context, int fd, int fd2); +void sys_setuid(Context* context, int new_uid, int new_euid); +void sys_setgid(Context* context, int new_gid, int new_egid); \ No newline at end of file diff --git a/kernel/src/sys/Syscall.cpp b/kernel/src/sys/Syscall.cpp index eb6b6d12..0378acb9 100644 --- a/kernel/src/sys/Syscall.cpp +++ b/kernel/src/sys/Syscall.cpp @@ -38,6 +38,8 @@ void Syscall::entry(Context* context) sys_getdents(context, (int)context->rdi, (struct luna_dirent*)context->rsi, (size_t)context->rdx); break; case SYS_dup2: sys_dup2(context, (int)context->rdi, (int)context->rsi); break; + case SYS_setuid: sys_setuid(context, (int)context->rdi, (int)context->rsi); break; + case SYS_setgid: sys_setgid(context, (int)context->rdi, (int)context->rsi); break; default: context->rax = -ENOSYS; break; } VMM::exit_syscall_context(); diff --git a/kernel/src/sys/id.cpp b/kernel/src/sys/id.cpp index 018a7027..3385428d 100644 --- a/kernel/src/sys/id.cpp +++ b/kernel/src/sys/id.cpp @@ -45,4 +45,52 @@ void sys_getprocid(Context* context, int field) context->rax = -EINVAL; return; } +} + +void sys_setuid(Context* context, int new_uid, int new_euid) +{ + Task* current_task = Scheduler::current_task(); + + if (!current_task->is_superuser()) + { + if (new_uid != current_task->uid && new_uid != current_task->euid) + { + context->rax = -EPERM; + return; + } + if (new_euid != current_task->euid && new_euid != current_task->uid) + { + context->rax = -EPERM; + return; + } + } + + current_task->uid = new_uid; + current_task->euid = new_euid; + + context->rax = 0; +} + +void sys_setgid(Context* context, int new_gid, int new_egid) +{ + Task* current_task = Scheduler::current_task(); + + if (!current_task->is_superuser()) + { + if (new_gid != current_task->gid && new_gid != current_task->egid) + { + context->rax = -EPERM; + return; + } + if (new_egid != current_task->egid && new_egid != current_task->gid) + { + context->rax = -EPERM; + return; + } + } + + current_task->gid = new_gid; + current_task->egid = new_egid; + + context->rax = 0; } \ No newline at end of file diff --git a/libs/libc/include/sys/syscall.h b/libs/libc/include/sys/syscall.h index 5b02e983..1a70c1e6 100644 --- a/libs/libc/include/sys/syscall.h +++ b/libs/libc/include/sys/syscall.h @@ -26,5 +26,7 @@ #define SYS_getdents 22 #define SYS_stat 23 #define SYS_dup2 24 +#define SYS_setuid 25 +#define SYS_setgid 26 #endif \ No newline at end of file diff --git a/libs/libc/src/syscall.cpp b/libs/libc/src/syscall.cpp index b5ae5667..c527bba2 100644 --- a/libs/libc/src/syscall.cpp +++ b/libs/libc/src/syscall.cpp @@ -26,6 +26,8 @@ extern "C" long syscall(long number, ...) case SYS_fstat: case SYS_stat: case SYS_dup2: + case SYS_setuid: + case SYS_setgid: case SYS_pstat: { arg arg0 = va_arg(ap, arg); arg arg1 = va_arg(ap, arg);