From a98df9e7438dffd8144e1cebd0e0339f1915f350 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 14 Aug 2023 09:50:52 +0200 Subject: [PATCH] kernel: Return EACCES when trying to apply execpromises to a setuid program Closes #41. --- kernel/src/sys/exec.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp index d83fe89a..22126d1e 100644 --- a/kernel/src/sys/exec.cpp +++ b/kernel/src/sys/exec.cpp @@ -74,6 +74,11 @@ Result sys_execve(Registers* regs, SyscallArgs args) kdbgln("exec: attempting to replace current image with %s", path.chars()); #endif + bool is_setuid = VFS::is_setuid(inode); + bool is_setgid = VFS::is_setgid(inode); + bool is_secure_environment = is_setgid || is_setuid; + if (is_secure_environment && current->execpromises >= 0) return err(EACCES); + auto loader = TRY(BinaryFormat::create_loader(inode)); #ifdef EXEC_DEBUG @@ -107,8 +112,8 @@ Result sys_execve(Registers* regs, SyscallArgs args) if (descriptor->flags & O_CLOEXEC) { descriptor = {}; } } - if (VFS::is_setuid(inode)) current->auth.euid = current->auth.suid = inode->metadata().uid; - if (VFS::is_setgid(inode)) current->auth.egid = current->auth.sgid = inode->metadata().gid; + if (is_setuid) current->auth.euid = current->auth.suid = inode->metadata().uid; + if (is_setgid) current->auth.egid = current->auth.sgid = inode->metadata().gid; current->name = path.chars(); @@ -160,8 +165,6 @@ Result sys_fork(Registers* regs, SyscallArgs) thread->current_directory_path = move(current_directory_path); thread->umask = current->umask; thread->parent = current; - // TODO: Should promises be inherited across fork()? We're assuming yes, as they're already reset on exec (unless - // execpromises has been set). Couldn't find any suitable documentation from OpenBSD about this. thread->promises = current->promises; thread->execpromises = current->execpromises; @@ -171,11 +174,7 @@ Result sys_fork(Registers* regs, SyscallArgs) memcpy(&thread->regs, regs, sizeof(*regs)); - for (int i = 0; i < NSIG; i++) - { - auto sighandler = current->signal_handlers[i].sa_handler; - thread->signal_handlers[i] = { .sa_handler = sighandler, .sa_mask = 0, .sa_flags = 0 }; - } + for (int i = 0; i < NSIG; i++) thread->signal_handlers[i] = current->signal_handlers[i]; thread->signal_mask = current->signal_mask; thread->set_return(0);