diff --git a/Kernel/FileSystem/InodeMetadata.h b/Kernel/FileSystem/InodeMetadata.h index 7e4ce3230c..f6b1d42d10 100644 --- a/Kernel/FileSystem/InodeMetadata.h +++ b/Kernel/FileSystem/InodeMetadata.h @@ -30,35 +30,35 @@ struct InodeMetadata { bool may_write(Process&) const; bool may_execute(Process&) const; - bool may_read(uid_t u, const HashTable& g) const + bool may_read(uid_t u, gid_t g, const HashTable& eg) const { if (u == 0) return true; if (uid == u) return mode & 0400; - if (g.contains(gid)) + if (gid == g || eg.contains(gid)) return mode & 0040; return mode & 0004; } - bool may_write(uid_t u, const HashTable& g) const + bool may_write(uid_t u, gid_t g, const HashTable& eg) const { if (u == 0) return true; if (uid == u) return mode & 0200; - if (g.contains(gid)) + if (gid == g || eg.contains(gid)) return mode & 0020; return mode & 0002; } - bool may_execute(uid_t u, const HashTable& g) const + bool may_execute(uid_t u, gid_t g, const HashTable& eg) const { if (u == 0) return true; if (uid == u) return mode & 0100; - if (g.contains(gid)) + if (gid == g || eg.contains(gid)) return mode & 0010; return mode & 0001; } diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 76359a6c61..642899a8b1 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -113,7 +113,7 @@ Vector Process::all_processes() bool Process::in_group(gid_t gid) const { - return m_gids.contains(gid); + return m_gid == gid || m_extra_gids.contains(gid); } Range Process::allocate_range(VirtualAddress vaddr, size_t size) @@ -530,8 +530,7 @@ pid_t Process::sys$fork(RegisterDump& regs) child->m_master_tls_region = &child->m_regions.last(); } - for (auto gid : m_gids) - child->m_gids.set(gid); + child->m_extra_gids = m_extra_gids; auto& child_tss = child_first_thread->m_tss; child_tss.eax = 0; // fork() returns 0 in the child :^) @@ -605,7 +604,7 @@ int Process::do_exec(String path, Vector arguments, Vector envir auto description = result.value(); auto metadata = description->metadata(); - if (!metadata.may_execute(m_euid, m_gids)) + if (!metadata.may_execute(*this)) return -EACCES; if (!metadata.size) @@ -789,7 +788,7 @@ KResultOr> Process::find_shebang_interpreter_for_executable(const auto description = result.value(); auto metadata = description->metadata(); - if (!metadata.may_execute(m_euid, m_gids)) + if (!metadata.may_execute(*this)) return KResult(-EACCES); if (metadata.size < 3) @@ -985,7 +984,7 @@ Process::Process(Thread*& first_thread, const String& name, uid_t uid, gid_t gid else first_thread = new Thread(*this); - m_gids.set(m_gid); + //m_gids.set(m_gid); if (fork_parent) { m_sid = fork_parent->m_sid; @@ -2247,13 +2246,13 @@ int Process::sys$getgroups(ssize_t count, gid_t* gids) if (count < 0) return -EINVAL; if (!count) - return m_gids.size(); - if (count != (int)m_gids.size()) + return m_extra_gids.size(); + if (count != (int)m_extra_gids.size()) return -EINVAL; - if (!validate_write_typed(gids, m_gids.size())) + if (!validate_write_typed(gids, m_extra_gids.size())) return -EFAULT; size_t i = 0; - for (auto gid : m_gids) + for (auto gid : m_extra_gids) gids[i++] = gid; return 0; } @@ -2266,10 +2265,12 @@ int Process::sys$setgroups(ssize_t count, const gid_t* gids) return -EPERM; if (!validate_read(gids, count)) return -EFAULT; - m_gids.clear(); - m_gids.set(m_gid); - for (int i = 0; i < count; ++i) - m_gids.set(gids[i]); + m_extra_gids.clear(); + for (int i = 0; i < count; ++i) { + if (gids[i] == m_gid) + continue; + m_extra_gids.set(gids[i]); + } return 0; } diff --git a/Kernel/Process.h b/Kernel/Process.h index 55811c4e44..100d11b06f 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -72,7 +72,7 @@ public: pid_t pgid() const { return m_pgid; } uid_t uid() const { return m_uid; } gid_t gid() const { return m_gid; } - const HashTable& gids() const { return m_gids; } + const HashTable& extra_gids() const { return m_extra_gids; } uid_t euid() const { return m_euid; } gid_t egid() const { return m_egid; } pid_t ppid() const { return m_ppid; } @@ -381,7 +381,7 @@ private: static void notify_waiters(pid_t waitee, int exit_status, int signal); - HashTable m_gids; + HashTable m_extra_gids; int m_next_tid { 0 }; @@ -502,17 +502,17 @@ inline void Process::for_each_in_pgrp(pid_t pgid, Callback callback) inline bool InodeMetadata::may_read(Process& process) const { - return may_read(process.euid(), process.gids()); + return may_read(process.euid(), process.egid(), process.extra_gids()); } inline bool InodeMetadata::may_write(Process& process) const { - return may_write(process.euid(), process.gids()); + return may_write(process.euid(), process.egid(), process.extra_gids()); } inline bool InodeMetadata::may_execute(Process& process) const { - return may_execute(process.euid(), process.gids()); + return may_execute(process.euid(), process.egid(), process.extra_gids()); } inline int Thread::pid() const