From 411c6c40cd97d39837787f55c926721a8b6ef295 Mon Sep 17 00:00:00 2001 From: apio Date: Thu, 11 May 2023 19:49:03 +0200 Subject: [PATCH] kernel: Add the fchmodat() and fchownat() system calls --- kernel/src/sys/id.cpp | 31 ++++++++++++++++++------------- libc/src/sys/stat.cpp | 2 +- libc/src/unistd.cpp | 2 +- libluna/include/luna/Syscall.h | 2 +- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/kernel/src/sys/id.cpp b/kernel/src/sys/id.cpp index 608a7a3f..f40c92a1 100644 --- a/kernel/src/sys/id.cpp +++ b/kernel/src/sys/id.cpp @@ -1,6 +1,7 @@ #include "memory/MemoryManager.h" #include "sys/Syscall.h" #include "thread/Scheduler.h" +#include Result sys_getpid(Registers*, SyscallArgs) { @@ -94,33 +95,37 @@ Result sys_setegid(Registers*, SyscallArgs args) return 0; } -Result sys_chmod(Registers*, SyscallArgs args) +Result 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 sys_chown(Registers*, SyscallArgs args) +Result 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)); diff --git a/libc/src/sys/stat.cpp b/libc/src/sys/stat.cpp index 6349bb5a..6cf4c737 100644 --- a/libc/src/sys/stat.cpp +++ b/libc/src/sys/stat.cpp @@ -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); } diff --git a/libc/src/unistd.cpp b/libc/src/unistd.cpp index 1f6c0c62..6fc7dce7 100644 --- a/libc/src/unistd.cpp +++ b/libc/src/unistd.cpp @@ -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); } diff --git a/libluna/include/luna/Syscall.h b/libluna/include/luna/Syscall.h index 5210cb83..e1d1354c 100644 --- a/libluna/include/luna/Syscall.h +++ b/libluna/include/luna/Syscall.h @@ -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