diff options
Diffstat (limited to 'Kernel/Process.cpp')
-rw-r--r-- | Kernel/Process.cpp | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 971ad69b04..3e95de39c3 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -565,6 +565,7 @@ pid_t Process::sys$fork(RegisterDump& regs) { Thread* child_first_thread = nullptr; auto* child = new Process(child_first_thread, m_name, m_uid, m_gid, m_pid, m_ring, m_cwd, m_executable, m_tty, this); + child->m_root_directory = m_root_directory; #ifdef FORK_DEBUG dbgprintf("fork: child=%p\n", child); @@ -966,15 +967,21 @@ Process* Process::create_user_process(Thread*& first_thread, const String& path, arguments.append(parts.last()); } RefPtr<Custody> cwd; + RefPtr<Custody> root; { InterruptDisabler disabler; - if (auto* parent = Process::from_pid(parent_pid)) + if (auto* parent = Process::from_pid(parent_pid)) { cwd = parent->m_cwd; + root = parent->m_root_directory; + } } if (!cwd) cwd = VFS::the().root_custody(); + if (!root) + root = VFS::the().root_custody(); + auto* process = new Process(first_thread, parts.take_last(), uid, gid, parent_pid, Ring3, move(cwd), nullptr, tty); error = process->exec(path, move(arguments), move(environment)); @@ -2650,6 +2657,7 @@ void Process::finalize() m_tty = nullptr; m_executable = nullptr; m_cwd = nullptr; + m_root_directory = nullptr; m_elf_loader = nullptr; disown_all_shared_buffers(); @@ -4127,3 +4135,29 @@ int Process::sys$set_process_boost(pid_t pid, int amount) process->m_priority_boost = amount; return 0; } + +int Process::sys$chroot(const char* user_path, size_t path_length) +{ + if (!is_superuser()) + return -EPERM; + auto path = get_syscall_path_argument(user_path, path_length); + if (path.is_error()) + return path.error(); + auto directory_or_error = VFS::the().open_directory(path.value(), current_directory()); + if (directory_or_error.is_error()) + return directory_or_error.error(); + set_root_directory(Custody::create(nullptr, "", directory_or_error.value()->inode())); + return 0; +} + +Custody& Process::root_directory() +{ + if (!m_root_directory) + m_root_directory = VFS::the().root_custody(); + return *m_root_directory; +} + +void Process::set_root_directory(const Custody& root) +{ + m_root_directory = root; +} |