Ver Fonte

Kernel: Use real UID/GID when checking for file access

This aligns the rest of the system with POSIX, who says that access(2)
must check against the real UID and GID, not effective ones.
sin-ack há 2 anos atrás
pai
commit
fa692e13f9

+ 9 - 6
Kernel/FileSystem/InodeMetadata.cpp

@@ -9,19 +9,22 @@
 
 namespace Kernel {
 
-bool InodeMetadata::may_read(Credentials const& credentials) const
+bool InodeMetadata::may_read(Credentials const& credentials, UseEffectiveIDs use_effective_ids) const
 {
-    return may_read(credentials.euid(), credentials.egid(), credentials.extra_gids());
+    bool eids = use_effective_ids == UseEffectiveIDs::Yes;
+    return may_read(eids ? credentials.euid() : credentials.uid(), eids ? credentials.egid() : credentials.gid(), credentials.extra_gids());
 }
 
-bool InodeMetadata::may_write(Credentials const& credentials) const
+bool InodeMetadata::may_write(Credentials const& credentials, UseEffectiveIDs use_effective_ids) const
 {
-    return may_write(credentials.euid(), credentials.egid(), credentials.extra_gids());
+    bool eids = use_effective_ids == UseEffectiveIDs::Yes;
+    return may_write(eids ? credentials.euid() : credentials.uid(), eids ? credentials.egid() : credentials.gid(), credentials.extra_gids());
 }
 
-bool InodeMetadata::may_execute(Credentials const& credentials) const
+bool InodeMetadata::may_execute(Credentials const& credentials, UseEffectiveIDs use_effective_ids) const
 {
-    return may_execute(credentials.euid(), credentials.egid(), credentials.extra_gids());
+    bool eids = use_effective_ids == UseEffectiveIDs::Yes;
+    return may_execute(eids ? credentials.euid() : credentials.uid(), eids ? credentials.egid() : credentials.gid(), credentials.extra_gids());
 }
 
 }

+ 8 - 3
Kernel/FileSystem/InodeMetadata.h

@@ -36,12 +36,17 @@ inline bool is_sticky(mode_t mode) { return (mode & S_ISVTX) == S_ISVTX; }
 inline bool is_setuid(mode_t mode) { return (mode & S_ISUID) == S_ISUID; }
 inline bool is_setgid(mode_t mode) { return (mode & S_ISGID) == S_ISGID; }
 
+enum class UseEffectiveIDs {
+    Yes,
+    No
+};
+
 struct InodeMetadata {
     bool is_valid() const { return inode.is_valid(); }
 
-    bool may_read(Credentials const&) const;
-    bool may_write(Credentials const&) const;
-    bool may_execute(Credentials const&) const;
+    bool may_read(Credentials const&, UseEffectiveIDs = UseEffectiveIDs::Yes) const;
+    bool may_write(Credentials const&, UseEffectiveIDs = UseEffectiveIDs::Yes) const;
+    bool may_execute(Credentials const&, UseEffectiveIDs = UseEffectiveIDs::Yes) const;
 
     bool may_read(UserID u, GroupID g, Span<GroupID const> eg) const
     {

+ 3 - 3
Kernel/FileSystem/VirtualFileSystem.cpp

@@ -530,17 +530,17 @@ ErrorOr<void> VirtualFileSystem::access(Credentials const& credentials, StringVi
     auto& inode = custody->inode();
     auto metadata = inode.metadata();
     if (mode & R_OK) {
-        if (!metadata.may_read(credentials))
+        if (!metadata.may_read(credentials, UseEffectiveIDs::No))
             return EACCES;
     }
     if (mode & W_OK) {
-        if (!metadata.may_write(credentials))
+        if (!metadata.may_write(credentials, UseEffectiveIDs::No))
             return EACCES;
         if (custody->is_readonly())
             return EROFS;
     }
     if (mode & X_OK) {
-        if (!metadata.may_execute(credentials))
+        if (!metadata.may_execute(credentials, UseEffectiveIDs::No))
             return EACCES;
     }
     return {};