From 29b3d95004471578e915f1feee892288b18606f3 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 10 Jan 2020 23:48:44 +0100 Subject: [PATCH] Kernel: Expose a process's filesystem root as a /proc/PID/root symlink In order to preserve the absolute path of the process root, we save the custody used by chroot() before stripping it to become the new "/". There's probably a better way to do this. --- Kernel/FileSystem/ProcFS.cpp | 11 +++++++++++ Kernel/Process.cpp | 8 ++++++++ Kernel/Process.h | 2 ++ 3 files changed, 21 insertions(+) diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index ef4eeb0717..4a5c2c7130 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -80,6 +80,7 @@ enum ProcFileType { FI_PID_fds, FI_PID_exe, // symlink FI_PID_cwd, // symlink + FI_PID_root, // symlink FI_PID_fd, // directory __FI_PID_End, @@ -571,6 +572,14 @@ Optional procfs$pid_cwd(InodeIdentifier identifier) return handle->process().current_directory().absolute_path().to_byte_buffer(); } +Optional procfs$pid_root(InodeIdentifier identifier) +{ + auto handle = ProcessInspectionHandle::from_pid(to_pid(identifier)); + if (!handle) + return {}; + return handle->process().root_directory_for_procfs().absolute_path().to_byte_buffer(); +} + Optional procfs$self(InodeIdentifier) { char buffer[16]; @@ -1030,6 +1039,7 @@ InodeMetadata ProcFSInode::metadata() const break; case FI_PID_cwd: case FI_PID_exe: + case FI_PID_root: metadata.mode = 0120400; break; case FI_Root: @@ -1408,6 +1418,7 @@ ProcFS::ProcFS() m_entries[FI_PID_fds] = { "fds", FI_PID_fds, false, procfs$pid_fds }; m_entries[FI_PID_exe] = { "exe", FI_PID_exe, false, procfs$pid_exe }; m_entries[FI_PID_cwd] = { "cwd", FI_PID_cwd, false, procfs$pid_cwd }; + m_entries[FI_PID_root] = { "root", FI_PID_root, false, procfs$pid_root }; m_entries[FI_PID_fd] = { "fd", FI_PID_fd, false }; } diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 3e95de39c3..52d860fe14 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -4146,6 +4146,7 @@ int Process::sys$chroot(const char* user_path, size_t path_length) auto directory_or_error = VFS::the().open_directory(path.value(), current_directory()); if (directory_or_error.is_error()) return directory_or_error.error(); + m_root_directory_for_procfs = directory_or_error.value(); set_root_directory(Custody::create(nullptr, "", directory_or_error.value()->inode())); return 0; } @@ -4157,6 +4158,13 @@ Custody& Process::root_directory() return *m_root_directory; } +Custody& Process::root_directory_for_procfs() +{ + if (!m_root_directory_for_procfs) + m_root_directory_for_procfs = root_directory(); + return *m_root_directory_for_procfs; +} + void Process::set_root_directory(const Custody& root) { m_root_directory = root; diff --git a/Kernel/Process.h b/Kernel/Process.h index d76c4bd551..f2c9e79f12 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -311,6 +311,7 @@ public: u32 priority_boost() const { return m_priority_boost; } Custody& root_directory(); + Custody& root_directory_for_procfs(); void set_root_directory(const Custody&); private: @@ -374,6 +375,7 @@ private: RefPtr m_executable; RefPtr m_cwd; RefPtr m_root_directory; + RefPtr m_root_directory_for_procfs; RefPtr m_tty;