2023-04-08 12:47:34 +00:00
|
|
|
#include "memory/MemoryManager.h"
|
2023-03-11 21:19:58 +00:00
|
|
|
#include "sys/Syscall.h"
|
|
|
|
#include "thread/Scheduler.h"
|
2023-05-11 17:49:03 +00:00
|
|
|
#include <bits/atfile.h>
|
2023-03-11 21:19:58 +00:00
|
|
|
|
|
|
|
Result<u64> sys_getpid(Registers*, SyscallArgs)
|
|
|
|
{
|
|
|
|
return Scheduler::current()->id;
|
|
|
|
}
|
2023-03-24 16:39:55 +00:00
|
|
|
|
|
|
|
Result<u64> sys_getppid(Registers*, SyscallArgs)
|
|
|
|
{
|
2023-05-04 20:58:04 +00:00
|
|
|
auto* parent = Scheduler::current()->parent;
|
|
|
|
|
|
|
|
return parent ? parent->id : 0;
|
2023-03-24 16:39:55 +00:00
|
|
|
}
|
2023-04-08 11:50:18 +00:00
|
|
|
|
|
|
|
Result<u64> sys_getuid(Registers*, SyscallArgs)
|
|
|
|
{
|
|
|
|
return Scheduler::current()->auth.uid;
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<u64> sys_geteuid(Registers*, SyscallArgs)
|
|
|
|
{
|
|
|
|
return Scheduler::current()->auth.euid;
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<u64> sys_getgid(Registers*, SyscallArgs)
|
|
|
|
{
|
|
|
|
return Scheduler::current()->auth.gid;
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<u64> sys_getegid(Registers*, SyscallArgs)
|
|
|
|
{
|
|
|
|
return Scheduler::current()->auth.egid;
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<u64> sys_setuid(Registers*, SyscallArgs args)
|
|
|
|
{
|
|
|
|
u32 uid = (u32)args[0];
|
|
|
|
|
|
|
|
Credentials& auth = Scheduler::current()->auth;
|
|
|
|
|
|
|
|
if (auth.euid == 0)
|
|
|
|
{
|
|
|
|
auth.uid = auth.euid = auth.suid = uid;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uid != auth.uid && uid != auth.suid) return err(EPERM);
|
|
|
|
auth.euid = uid;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<u64> sys_seteuid(Registers*, SyscallArgs args)
|
|
|
|
{
|
|
|
|
u32 uid = (u32)args[0];
|
|
|
|
|
|
|
|
Credentials& auth = Scheduler::current()->auth;
|
|
|
|
|
|
|
|
if (auth.euid != 0 && uid != auth.uid && uid != auth.suid) return err(EPERM);
|
|
|
|
auth.euid = uid;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<u64> sys_setgid(Registers*, SyscallArgs args)
|
|
|
|
{
|
|
|
|
u32 gid = (u32)args[0];
|
|
|
|
|
|
|
|
Credentials& auth = Scheduler::current()->auth;
|
|
|
|
|
|
|
|
if (auth.euid == 0)
|
|
|
|
{
|
|
|
|
auth.gid = auth.egid = auth.sgid = gid;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gid != auth.gid && gid != auth.sgid) return err(EPERM);
|
|
|
|
auth.egid = gid;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<u64> sys_setegid(Registers*, SyscallArgs args)
|
|
|
|
{
|
|
|
|
u32 gid = (u32)args[0];
|
|
|
|
|
|
|
|
Credentials& auth = Scheduler::current()->auth;
|
|
|
|
|
|
|
|
if (auth.euid != 0 && gid != auth.gid && gid != auth.sgid) return err(EPERM);
|
|
|
|
auth.egid = gid;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2023-04-08 12:47:34 +00:00
|
|
|
|
2023-07-11 09:51:07 +00:00
|
|
|
Result<u64> sys_setpgid(Registers*, SyscallArgs args)
|
|
|
|
{
|
|
|
|
pid_t pid = (pid_t)args[0];
|
|
|
|
pid_t pgid = (pid_t)args[1];
|
|
|
|
|
|
|
|
auto* current = Scheduler::current();
|
|
|
|
if (pid == 0) pid = (pid_t)current->id;
|
|
|
|
if (pgid == 0) pgid = (pid_t)current->id;
|
|
|
|
|
|
|
|
if (pgid < 0) return err(EINVAL);
|
|
|
|
|
|
|
|
auto* thread = TRY(Result<Thread*>::from_option(Scheduler::find_by_pid(pid), ESRCH));
|
|
|
|
if (thread != current && thread->parent != current) return err(ESRCH);
|
|
|
|
|
|
|
|
// FIXME: Weird session stuff, we don't have that currently.
|
|
|
|
|
|
|
|
if (thread->has_called_exec) return err(EPERM);
|
|
|
|
|
|
|
|
if (pgid != (pid_t)current->id)
|
|
|
|
{
|
|
|
|
bool pgid_exists = false;
|
|
|
|
Scheduler::for_each_in_process_group(pgid, [&pgid_exists](Thread*) {
|
|
|
|
pgid_exists = true;
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
if (!pgid_exists) return err(EPERM);
|
|
|
|
}
|
|
|
|
|
|
|
|
thread->pgid = (u64)pgid;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-05-11 17:49:03 +00:00
|
|
|
Result<u64> sys_fchmodat(Registers*, SyscallArgs args)
|
2023-04-08 12:47:34 +00:00
|
|
|
{
|
2023-05-11 17:49:03 +00:00
|
|
|
int dirfd = (int)args[0];
|
|
|
|
auto path = TRY(MemoryManager::strdup_from_user(args[1]));
|
|
|
|
mode_t mode = (mode_t)args[2];
|
|
|
|
int flags = (int)args[3];
|
2023-04-08 12:47:34 +00:00
|
|
|
|
2023-05-11 17:49:03 +00:00
|
|
|
auto* current = Scheduler::current();
|
2023-04-08 12:47:34 +00:00
|
|
|
|
2023-05-20 19:46:31 +00:00
|
|
|
auto inode = TRY(current->resolve_atfile(dirfd, path, flags & AT_EMPTY_PATH, !(flags & AT_SYMLINK_NOFOLLOW)));
|
2023-04-08 12:47:34 +00:00
|
|
|
|
2023-05-11 17:49:03 +00:00
|
|
|
if (current->auth.euid != 0 && current->auth.euid != inode->uid()) return err(EPERM);
|
2023-04-08 12:47:34 +00:00
|
|
|
|
|
|
|
TRY(inode->chmod(mode));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-05-11 17:49:03 +00:00
|
|
|
Result<u64> sys_fchownat(Registers*, SyscallArgs args)
|
2023-04-08 12:47:34 +00:00
|
|
|
{
|
2023-05-11 17:49:03 +00:00
|
|
|
int dirfd = (int)args[0];
|
|
|
|
auto path = TRY(MemoryManager::strdup_from_user(args[1]));
|
|
|
|
u32 uid = (u32)args[2];
|
|
|
|
u32 gid = (u32)args[3];
|
|
|
|
int flags = (int)args[4];
|
2023-04-08 12:47:34 +00:00
|
|
|
|
2023-05-11 17:49:03 +00:00
|
|
|
auto* current = Scheduler::current();
|
2023-04-08 12:47:34 +00:00
|
|
|
|
2023-05-20 19:46:31 +00:00
|
|
|
auto inode = TRY(current->resolve_atfile(dirfd, path, flags & AT_EMPTY_PATH, !(flags & AT_SYMLINK_NOFOLLOW)));
|
2023-04-08 12:47:34 +00:00
|
|
|
|
2023-05-11 17:49:03 +00:00
|
|
|
if (current->auth.euid != 0) return err(EPERM);
|
2023-04-08 12:47:34 +00:00
|
|
|
|
|
|
|
TRY(inode->chown(uid == (u32)-1 ? inode->uid() : uid, gid == (u32)-1 ? inode->gid() : gid));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|