From b2746a5f014fb5b7b56855052cba7737074e9f33 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sun, 16 Oct 2022 16:52:12 -0300 Subject: [PATCH] syscalls: mkdir and chroot --- src/arch/x86_64/syscall.asm | 6 ++++- src/sys/syscalls/chroot.c | 52 +++++++++++++++++++++++++++++++++++++ src/sys/syscalls/mkdir.c | 26 ++++++++++++++++--- 3 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 src/sys/syscalls/chroot.c diff --git a/src/arch/x86_64/syscall.asm b/src/arch/x86_64/syscall.asm index a82595db..c5710b74 100644 --- a/src/arch/x86_64/syscall.asm +++ b/src/arch/x86_64/syscall.asm @@ -32,7 +32,9 @@ extern syscall_umask extern syscall_poll extern syscall_fchmodat extern syscall_openat -func_count equ 31 +extern syscall_chroot +extern syscall_mkdirat +func_count equ 33 func_table: @@ -67,6 +69,8 @@ func_table: dq syscall_poll dq syscall_fchmodat dq syscall_openat + dq syscall_chroot + dq syscall_mkdirat section .text global asm_syscall_entry diff --git a/src/sys/syscalls/chroot.c b/src/sys/syscalls/chroot.c new file mode 100644 index 00000000..80fbb055 --- /dev/null +++ b/src/sys/syscalls/chroot.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include + +syscallret syscall_chroot(const char* path){ + + syscallret retv; + retv.ret = -1; + + if(path > USER_SPACE_END){ + retv.errno = EFAULT; + return retv; + } + + size_t len = strlen(path); + + char buff[len+1]; + + strcpy(buff, path); + + proc_t* proc = arch_getcls()->thread->proc; + + vnode_t* vnode; + + retv.errno = vfs_open(&vnode, + buff[0] == '/' ? proc->root : proc->cwd, + buff + ); + + if(retv.errno) + return retv; + + if(GETTYPE(vnode->st.st_mode) != TYPE_DIR){ + retv.errno = ENOTDIR; + goto _ret; + } + + dirnode_t* oldroot = proc->root; + proc->root = (dirnode_t*)vnode; + + retv.errno = 0; + retv.ret = 0; + + _ret: + + vfs_close(vnode); + + return retv; + +} diff --git a/src/sys/syscalls/mkdir.c b/src/sys/syscalls/mkdir.c index fad1d468..f0af2205 100644 --- a/src/sys/syscalls/mkdir.c +++ b/src/sys/syscalls/mkdir.c @@ -4,7 +4,7 @@ #include #include -syscallret syscall_mkdir(const char* pathname, mode_t mode){ +syscallret syscall_mkdirat(int dirfd, const char* pathname, mode_t mode){ syscallret retv; retv.ret = -1; @@ -19,12 +19,32 @@ syscallret syscall_mkdir(const char* pathname, mode_t mode){ strcpy(path, pathname); - retv.errno = vfs_mkdir(path[0] == '/' ? proc->root : proc->cwd, path, mode & ~proc->umask); + dirnode_t* target; + fd_t* targetfd; + + if(dirfd != AT_FDCWD){ + + retv.errno = fd_access(&proc->fdtable, &targetfd, dirfd); + if(retv.errno) + return retv; + + target = targetfd->node; + + } + else target = proc->cwd; + + retv.errno = vfs_mkdir(path[0] == '/' ? proc->root : target, path, mode & ~proc->umask); if(retv.errno == 0) retv.ret = 0; - + + if(dirfd != AT_FDCWD) + fd_release(targetfd); return retv; } + +syscallret syscall_mkdir(const char* pathname, mode_t mode){ + return syscall_mkdirat(AT_FDCWD, pathname, mode); +}