From 30215963b2baf5dbbe1e94df8b92076c7f955cbf Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 29 Aug 2025 01:40:56 +0300 Subject: [PATCH] Kernel: Fix /proc//exe permissions --- kernel/include/kernel/FS/ProcFS/Inode.h | 29 +++++++++++++++++++++ kernel/include/kernel/Process.h | 1 + kernel/kernel/FS/ProcFS/Inode.cpp | 34 +++++++++++++++++-------- kernel/kernel/Process.cpp | 8 ++++++ 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/kernel/include/kernel/FS/ProcFS/Inode.h b/kernel/include/kernel/FS/ProcFS/Inode.h index 011fff5eaa..ca55a92c27 100644 --- a/kernel/include/kernel/FS/ProcFS/Inode.h +++ b/kernel/include/kernel/FS/ProcFS/Inode.h @@ -57,6 +57,35 @@ namespace Kernel size_t (Process::*m_callback)(off_t, BAN::ByteSpan) const; }; + class ProcSymlinkProcessInode final : public TmpInode + { + public: + static BAN::ErrorOr> create_new(Process& process, BAN::ErrorOr (Process::*callback)() const, TmpFileSystem&, mode_t); + ~ProcSymlinkProcessInode() = default; + + virtual uid_t uid() const override { return m_process.credentials().ruid(); } + virtual gid_t gid() const override { return m_process.credentials().rgid(); } + + protected: + virtual BAN::ErrorOr link_target_impl() override; + + // You may not write here and this is always non blocking + virtual BAN::ErrorOr write_impl(off_t, BAN::ConstByteSpan) override { return BAN::Error::from_errno(EINVAL); } + virtual BAN::ErrorOr truncate_impl(size_t) override { return BAN::Error::from_errno(EINVAL); } + + virtual bool can_read_impl() const override { return false; } + virtual bool can_write_impl() const override { return false; } + virtual bool has_error_impl() const override { return false; } + virtual bool has_hungup_impl() const override { return false; } + + private: + ProcSymlinkProcessInode(Process& process, BAN::ErrorOr (Process::*)() const, TmpFileSystem&, const TmpInodeInfo&); + + private: + Process& m_process; + BAN::ErrorOr (Process::*m_callback)() const; + }; + class ProcROInode final : public TmpInode { public: diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index b289cc611a..8d069905ea 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -225,6 +225,7 @@ namespace Kernel size_t proc_meminfo(off_t offset, BAN::ByteSpan) const; size_t proc_cmdline(off_t offset, BAN::ByteSpan) const; size_t proc_environ(off_t offset, BAN::ByteSpan) const; + BAN::ErrorOr proc_executable() const; BAN::StringView executable() const { return m_executable; } diff --git a/kernel/kernel/FS/ProcFS/Inode.cpp b/kernel/kernel/FS/ProcFS/Inode.cpp index 91a9ac369e..588bea70fa 100644 --- a/kernel/kernel/FS/ProcFS/Inode.cpp +++ b/kernel/kernel/FS/ProcFS/Inode.cpp @@ -17,16 +17,7 @@ namespace Kernel TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_meminfo, fs, 0400)), "meminfo"_sv)); TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_cmdline, fs, 0400)), "cmdline"_sv)); TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_environ, fs, 0400)), "environ"_sv)); - - TRY(inode->link_inode(*MUST(ProcSymlinkInode::create_new( - [](void* process) -> BAN::ErrorOr - { - BAN::String result; - TRY(result.append(static_cast(process)->executable())); - return result; - }, - &process, fs, 0400, process.credentials().ruid(), process.credentials().ruid() - )), "exe"_sv)); + TRY(inode->link_inode(*MUST(ProcSymlinkProcessInode::create_new(process, &Process::proc_executable, fs, 0400)), "exe"_sv)); return inode; } @@ -70,6 +61,29 @@ namespace Kernel return (m_process.*m_callback)(offset, buffer); } + BAN::ErrorOr> ProcSymlinkProcessInode::create_new(Process& process, BAN::ErrorOr (Process::*callback)() const, TmpFileSystem& fs, mode_t mode) + { + auto inode_info = create_inode_info(Mode::IFLNK | mode, 0, 0); + + auto* inode_ptr = new ProcSymlinkProcessInode(process, callback, fs, inode_info); + if (inode_ptr == nullptr) + return BAN::Error::from_errno(ENOMEM); + return BAN::RefPtr::adopt(inode_ptr); + } + + ProcSymlinkProcessInode::ProcSymlinkProcessInode(Process& process, BAN::ErrorOr (Process::*callback)() const, TmpFileSystem& fs, const TmpInodeInfo& inode_info) + : TmpInode(fs, MUST(fs.allocate_inode(inode_info)), inode_info) + , m_process(process) + , m_callback(callback) + { + m_inode_info.mode |= Inode::Mode::IFLNK; + } + + BAN::ErrorOr ProcSymlinkProcessInode::link_target_impl() + { + return (m_process.*m_callback)(); + } + BAN::ErrorOr> ProcROInode::create_new(size_t (*callback)(off_t, BAN::ByteSpan), TmpFileSystem& fs, mode_t mode, uid_t uid, gid_t gid) { auto inode_info = create_inode_info(Mode::IFREG | mode, uid, gid); diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 093770ce87..8e738ab9d4 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -463,6 +463,14 @@ namespace Kernel return read_from_vec_of_str(m_environ, offset, buffer); } + BAN::ErrorOr Process::proc_executable() const + { + LockGuard _(m_process_lock); + BAN::String result; + TRY(result.append(m_executable)); + return result; + } + BAN::ErrorOr Process::find_file(int fd, const char* path, int flags) const { ASSERT(m_process_lock.is_locked());