kernel: Return EACCES when trying to apply execpromises to a setuid program

Closes #41.
This commit is contained in:
apio 2023-08-14 09:50:52 +02:00
parent e2a77bb3da
commit a98df9e743
Signed by: apio
GPG Key ID: B8A7D06E42258954

View File

@ -74,6 +74,11 @@ Result<u64> 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<u64> 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<u64> 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<u64> 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);