kernel: Add the fchmodat() and fchownat() system calls
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
apio 2023-05-11 19:49:03 +02:00
parent 4a3a92e9d4
commit 411c6c40cd
Signed by: apio
GPG Key ID: B8A7D06E42258954
4 changed files with 21 additions and 16 deletions

View File

@ -1,6 +1,7 @@
#include "memory/MemoryManager.h"
#include "sys/Syscall.h"
#include "thread/Scheduler.h"
#include <bits/atfile.h>
Result<u64> sys_getpid(Registers*, SyscallArgs)
{
@ -94,33 +95,37 @@ Result<u64> sys_setegid(Registers*, SyscallArgs args)
return 0;
}
Result<u64> sys_chmod(Registers*, SyscallArgs args)
Result<u64> sys_fchmodat(Registers*, SyscallArgs args)
{
auto path = TRY(MemoryManager::strdup_from_user(args[0]));
mode_t mode = (mode_t)args[1];
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];
Credentials& auth = Scheduler::current()->auth;
auto* current = Scheduler::current();
auto inode = TRY(VFS::resolve_path(path.chars(), auth, Scheduler::current()->current_directory));
auto inode = TRY(current->resolve_atfile(dirfd, path, flags & AT_EMPTY_PATH));
if (auth.euid != 0 && auth.euid != inode->uid()) return err(EPERM);
if (current->auth.euid != 0 && current->auth.euid != inode->uid()) return err(EPERM);
TRY(inode->chmod(mode));
return 0;
}
Result<u64> sys_chown(Registers*, SyscallArgs args)
Result<u64> sys_fchownat(Registers*, SyscallArgs args)
{
auto path = TRY(MemoryManager::strdup_from_user(args[0]));
u32 uid = (u32)args[1];
u32 gid = (u32)args[2];
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];
Credentials& auth = Scheduler::current()->auth;
auto* current = Scheduler::current();
auto inode = TRY(VFS::resolve_path(path.chars(), auth, Scheduler::current()->current_directory));
auto inode = TRY(current->resolve_atfile(dirfd, path, flags & AT_EMPTY_PATH));
if (auth.euid != 0) return err(EPERM);
if (current->auth.euid != 0) return err(EPERM);
TRY(inode->chown(uid == (u32)-1 ? inode->uid() : uid, gid == (u32)-1 ? inode->gid() : gid));

View File

@ -20,7 +20,7 @@ extern "C"
int chmod(const char* path, mode_t mode)
{
long rc = syscall(SYS_chmod, path, mode);
long rc = syscall(SYS_fchmodat, AT_FDCWD, path, mode, 0);
__errno_return(rc, int);
}

View File

@ -144,7 +144,7 @@ extern "C"
int chown(const char* path, uid_t uid, gid_t gid)
{
long rc = syscall(SYS_chown, path, uid, gid);
long rc = syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, 0);
__errno_return(rc, int);
}

View File

@ -3,7 +3,7 @@
#define enumerate_syscalls(_e) \
_e(exit) _e(clock_gettime) _e(mmap) _e(munmap) _e(usleep) _e(openat) _e(close) _e(read) _e(getpid) _e(write) \
_e(lseek) _e(mkdir) _e(execve) _e(mknod) _e(fork) _e(waitpid) _e(getppid) _e(fcntl) _e(getdents) _e(getuid) \
_e(geteuid) _e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(chmod) _e(chown) \
_e(geteuid) _e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(fchmodat) _e(fchownat) \
_e(ioctl) _e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe)
enum Syscalls