From 3def5238564325de8e193c679cc9fa0e22ea932f Mon Sep 17 00:00:00 2001 From: Tulio A M Mendes Date: Sun, 15 Feb 2026 05:18:03 -0300 Subject: [PATCH] =?utf8?q?feat:=20pivot=5Froot=20=E2=80=94=20syscall=20for?= =?utf8?q?=20swapping=20root=20filesystem?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- include/syscall.h | 2 ++ src/kernel/syscall.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/syscall.h b/include/syscall.h index 9f6aae0..cae9344 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -146,6 +146,8 @@ enum { SYSCALL_SENDMSG = 118, SYSCALL_RECVMSG = 119, + + SYSCALL_PIVOT_ROOT = 120, }; #endif diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 0e03f02..896e68f 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -4494,6 +4494,34 @@ static void socket_syscall_dispatch(struct registers* regs, uint32_t syscall_no) return; } + if (syscall_no == SYSCALL_PIVOT_ROOT) { + if (!current_process || current_process->euid != 0) { + sc_ret(regs) = (uint32_t)-EPERM; + return; + } + const char* user_new = (const char*)sc_arg0(regs); + const char* user_put = (const char*)sc_arg1(regs); + char knew[128], kput[128]; + if (path_resolve_user(user_new, knew, sizeof(knew)) < 0 || + path_resolve_user(user_put, kput, sizeof(kput)) < 0) { + sc_ret(regs) = (uint32_t)-EFAULT; + return; + } + fs_node_t* new_root = vfs_lookup(knew); + if (!new_root || !(new_root->flags & FS_DIRECTORY)) { + sc_ret(regs) = (uint32_t)-EINVAL; + return; + } + fs_node_t* old_root = fs_root; + fs_root = new_root; + (void)vfs_mount("/", new_root); + if (old_root) { + (void)vfs_mount(kput, old_root); + } + sc_ret(regs) = 0; + return; + } + sc_ret(regs) = (uint32_t)-ENOSYS; } -- 2.43.0