diff --git a/Kernel/FileSystem/DevPtsFS.cpp b/Kernel/FileSystem/DevPtsFS.cpp index 02bce17d14..5a107a1c44 100644 --- a/Kernel/FileSystem/DevPtsFS.cpp +++ b/Kernel/FileSystem/DevPtsFS.cpp @@ -51,13 +51,13 @@ InodeIdentifier DevPtsFS::root_inode() const return { fsid(), 1 }; } -RefPtr DevPtsFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, int& error) +RefPtr DevPtsFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, uid_t, gid_t, int& error) { error = -EROFS; return nullptr; } -RefPtr DevPtsFS::create_directory(InodeIdentifier, const String&, mode_t, int& error) +RefPtr DevPtsFS::create_directory(InodeIdentifier, const String&, mode_t, uid_t, gid_t, int& error) { error = -EROFS; return nullptr; diff --git a/Kernel/FileSystem/DevPtsFS.h b/Kernel/FileSystem/DevPtsFS.h index 2dae6c137e..ad342aebce 100644 --- a/Kernel/FileSystem/DevPtsFS.h +++ b/Kernel/FileSystem/DevPtsFS.h @@ -16,8 +16,8 @@ public: virtual const char* class_name() const override { return "DevPtsFS"; } virtual InodeIdentifier root_inode() const override; - virtual RefPtr create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) override; - virtual RefPtr create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) override; + virtual RefPtr create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) override; + virtual RefPtr create_directory(InodeIdentifier parentInode, const String& name, mode_t, uid_t, gid_t, int& error) override; virtual RefPtr get_inode(InodeIdentifier) const override; static void register_slave_pty(SlavePTY&); diff --git a/Kernel/FileSystem/Ext2FileSystem.cpp b/Kernel/FileSystem/Ext2FileSystem.cpp index 66d23fe7cf..5efadceb99 100644 --- a/Kernel/FileSystem/Ext2FileSystem.cpp +++ b/Kernel/FileSystem/Ext2FileSystem.cpp @@ -1284,7 +1284,7 @@ bool Ext2FS::set_block_allocation_state(BlockIndex block_index, bool new_state) return true; } -RefPtr Ext2FS::create_directory(InodeIdentifier parent_id, const String& name, mode_t mode, int& error) +RefPtr Ext2FS::create_directory(InodeIdentifier parent_id, const String& name, mode_t mode, uid_t uid, gid_t gid, int& error) { LOCKER(m_lock); ASSERT(parent_id.fsid() == fsid()); @@ -1296,7 +1296,7 @@ RefPtr Ext2FS::create_directory(InodeIdentifier parent_id, const String& // NOTE: When creating a new directory, make the size 1 block. // There's probably a better strategy here, but this works for now. - auto inode = create_inode(parent_id, name, mode, block_size(), 0, error); + auto inode = create_inode(parent_id, name, mode, block_size(), 0, uid, gid, error); if (!inode) return nullptr; @@ -1328,7 +1328,7 @@ RefPtr Ext2FS::create_directory(InodeIdentifier parent_id, const String& return inode; } -RefPtr Ext2FS::create_inode(InodeIdentifier parent_id, const String& name, mode_t mode, off_t size, dev_t dev, int& error) +RefPtr Ext2FS::create_inode(InodeIdentifier parent_id, const String& name, mode_t mode, off_t size, dev_t dev, uid_t uid, gid_t gid, int& error) { LOCKER(m_lock); ASSERT(parent_id.fsid() == fsid()); @@ -1378,8 +1378,8 @@ RefPtr Ext2FS::create_inode(InodeIdentifier parent_id, const String& name ext2_inode e2inode; memset(&e2inode, 0, sizeof(ext2_inode)); e2inode.i_mode = mode; - e2inode.i_uid = current->process().euid(); - e2inode.i_gid = current->process().egid(); + e2inode.i_uid = uid; + e2inode.i_gid = gid; e2inode.i_size = size; e2inode.i_atime = now.tv_sec; e2inode.i_ctime = now.tv_sec; diff --git a/Kernel/FileSystem/Ext2FileSystem.h b/Kernel/FileSystem/Ext2FileSystem.h index f8cfaa7bcb..f550ed3bc8 100644 --- a/Kernel/FileSystem/Ext2FileSystem.h +++ b/Kernel/FileSystem/Ext2FileSystem.h @@ -99,8 +99,8 @@ private: virtual const char* class_name() const override; virtual InodeIdentifier root_inode() const override; - virtual RefPtr create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) override; - virtual RefPtr create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) override; + virtual RefPtr create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) override; + virtual RefPtr create_directory(InodeIdentifier parentInode, const String& name, mode_t, uid_t, gid_t, int& error) override; virtual RefPtr get_inode(InodeIdentifier) const override; virtual void flush_writes() override; diff --git a/Kernel/FileSystem/FileSystem.h b/Kernel/FileSystem/FileSystem.h index 9538c6f132..b098cc0a62 100644 --- a/Kernel/FileSystem/FileSystem.h +++ b/Kernel/FileSystem/FileSystem.h @@ -58,8 +58,8 @@ public: u8 file_type { 0 }; }; - virtual RefPtr create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) = 0; - virtual RefPtr create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) = 0; + virtual RefPtr create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) = 0; + virtual RefPtr create_directory(InodeIdentifier parentInode, const String& name, mode_t, uid_t, gid_t, int& error) = 0; virtual RefPtr get_inode(InodeIdentifier) const = 0; diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index a65c7031db..95dd14447c 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -947,13 +947,13 @@ const char* ProcFS::class_name() const return "ProcFS"; } -RefPtr ProcFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, int&) +RefPtr ProcFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, uid_t, gid_t, int&) { kprintf("FIXME: Implement ProcFS::create_inode()?\n"); return {}; } -RefPtr ProcFS::create_directory(InodeIdentifier, const String&, mode_t, int& error) +RefPtr ProcFS::create_directory(InodeIdentifier, const String&, mode_t, uid_t, gid_t, int& error) { error = -EROFS; return nullptr; diff --git a/Kernel/FileSystem/ProcFS.h b/Kernel/FileSystem/ProcFS.h index 743482a844..c68f3c46e7 100644 --- a/Kernel/FileSystem/ProcFS.h +++ b/Kernel/FileSystem/ProcFS.h @@ -23,8 +23,8 @@ public: virtual InodeIdentifier root_inode() const override; virtual RefPtr get_inode(InodeIdentifier) const override; - virtual RefPtr create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, int& error) override; - virtual RefPtr create_directory(InodeIdentifier parent_id, const String& name, mode_t, int& error) override; + virtual RefPtr create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) override; + virtual RefPtr create_directory(InodeIdentifier parent_id, const String& name, mode_t, uid_t, gid_t, int& error) override; static void add_sys_bool(String&&, Lockable&, Function&& notify_callback = nullptr); static void add_sys_string(String&&, Lockable&, Function&& notify_callback = nullptr); diff --git a/Kernel/FileSystem/TmpFS.cpp b/Kernel/FileSystem/TmpFS.cpp index 2b80f23c8e..842a241d8a 100644 --- a/Kernel/FileSystem/TmpFS.cpp +++ b/Kernel/FileSystem/TmpFS.cpp @@ -62,7 +62,7 @@ RefPtr TmpFS::get_inode(InodeIdentifier identifier) const return it->value; } -RefPtr TmpFS::create_inode(InodeIdentifier parent_id, const String& name, mode_t mode, off_t size, dev_t dev, int& error) +RefPtr TmpFS::create_inode(InodeIdentifier parent_id, const String& name, mode_t mode, off_t size, dev_t dev, uid_t uid, gid_t gid, int& error) { LOCKER(m_lock); ASSERT(parent_id.fsid() == fsid()); @@ -75,8 +75,8 @@ RefPtr TmpFS::create_inode(InodeIdentifier parent_id, const String& name, InodeMetadata metadata; metadata.mode = mode; - metadata.uid = current->process().euid(); - metadata.gid = current->process().egid(); + metadata.uid = uid; + metadata.gid = gid; metadata.atime = now.tv_sec; metadata.ctime = now.tv_sec; metadata.mtime = now.tv_sec; @@ -91,12 +91,12 @@ RefPtr TmpFS::create_inode(InodeIdentifier parent_id, const String& name, return inode; } -RefPtr TmpFS::create_directory(InodeIdentifier parent_id, const String& name, mode_t mode, int& error) +RefPtr TmpFS::create_directory(InodeIdentifier parent_id, const String& name, mode_t mode, uid_t uid, gid_t gid, int& error) { // Ensure it's a directory. mode &= ~0170000; mode |= 0040000; - return create_inode(parent_id, name, mode, 0, 0, error); + return create_inode(parent_id, name, mode, 0, 0, uid, gid, error); } TmpFSInode::TmpFSInode(TmpFS& fs, InodeMetadata metadata, InodeIdentifier parent) diff --git a/Kernel/FileSystem/TmpFS.h b/Kernel/FileSystem/TmpFS.h index 0b15724b12..c5ff7bf383 100644 --- a/Kernel/FileSystem/TmpFS.h +++ b/Kernel/FileSystem/TmpFS.h @@ -22,8 +22,8 @@ public: virtual InodeIdentifier root_inode() const override; virtual RefPtr get_inode(InodeIdentifier) const override; - virtual RefPtr create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, int& error) override; - virtual RefPtr create_directory(InodeIdentifier parent_id, const String& name, mode_t, int& error) override; + virtual RefPtr create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) override; + virtual RefPtr create_directory(InodeIdentifier parent_id, const String& name, mode_t, uid_t, gid_t, int& error) override; private: TmpFS(); diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index 7d66f0c604..2578dd4b79 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -183,7 +183,7 @@ KResultOr VFS::lookup_metadata(StringView path, Custody& base, in return custody_or_error.value()->inode().metadata(); } -KResultOr> VFS::open(StringView path, int options, mode_t mode, Custody& base) +KResultOr> VFS::open(StringView path, int options, mode_t mode, Custody& base, Optional owner) { if ((options & O_CREAT) && (options & O_DIRECTORY)) return KResult(-EINVAL); @@ -196,7 +196,7 @@ KResultOr> VFS::open(StringView path, int options if (custody_or_error.is_error()) { if (custody_or_error.error() != -ENOENT) return custody_or_error.error(); - return create(path, options, mode, *parent_custody); + return create(path, options, mode, *parent_custody, move(owner)); } if (options & O_EXCL) return KResult(-EEXIST); @@ -263,14 +263,14 @@ KResult VFS::mknod(StringView path, mode_t mode, dev_t dev, Custody& base) FileSystemPath p(path); dbg() << "VFS::mknod: '" << p.basename() << "' mode=" << mode << " dev=" << dev << " in " << parent_inode.identifier(); int error; - auto new_file = parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), mode, 0, dev, error); + auto new_file = parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), mode, 0, dev, current->process().uid(), current->process().gid(), error); if (!new_file) return KResult(error); return KSuccess; } -KResultOr> VFS::create(StringView path, int options, mode_t mode, Custody& parent_custody) +KResultOr> VFS::create(StringView path, int options, mode_t mode, Custody& parent_custody, Optional owner) { (void)options; @@ -285,7 +285,10 @@ KResultOr> VFS::create(StringView path, int optio FileSystemPath p(path); dbg() << "VFS::create: '" << p.basename() << "' in " << parent_inode.identifier(); int error; - auto new_file = parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), mode, 0, 0, error); + + uid_t uid = owner.has_value() ? owner.value().uid : current->process().uid(); + gid_t gid = owner.has_value() ? owner.value().gid : current->process().gid(); + auto new_file = parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), mode, 0, 0, uid, gid, error); if (!new_file) return KResult(error); @@ -311,7 +314,7 @@ KResult VFS::mkdir(StringView path, mode_t mode, Custody& base) FileSystemPath p(path); dbg() << "VFS::mkdir: '" << p.basename() << "' in " << parent_inode.identifier(); int error; - auto new_dir = parent_inode.fs().create_directory(parent_inode.identifier(), p.basename(), mode, error); + auto new_dir = parent_inode.fs().create_directory(parent_inode.identifier(), p.basename(), mode, current->process().uid(), current->process().gid(), error); if (new_dir) return KSuccess; return KResult(error); @@ -556,7 +559,7 @@ KResult VFS::symlink(StringView target, StringView linkpath, Custody& base) FileSystemPath p(linkpath); dbg() << "VFS::symlink: '" << p.basename() << "' (-> '" << target << "') in " << parent_inode.identifier(); int error; - auto new_file = parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), 0120644, 0, 0, error); + auto new_file = parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), 0120644, 0, 0, current->process().uid(), current->process().gid(), error); if (!new_file) return KResult(error); ssize_t nwritten = new_file->write_bytes(0, target.length(), (const u8*)target.characters_without_null_termination(), nullptr); diff --git a/Kernel/FileSystem/VirtualFileSystem.h b/Kernel/FileSystem/VirtualFileSystem.h index 626e844b49..2e8f92866d 100644 --- a/Kernel/FileSystem/VirtualFileSystem.h +++ b/Kernel/FileSystem/VirtualFileSystem.h @@ -31,6 +31,11 @@ class Custody; class Device; class FileDescription; +struct UidAndGid { + uid_t uid; + gid_t gid; +}; + class VFS { AK_MAKE_ETERNAL public: @@ -62,8 +67,8 @@ public: KResult mount(NonnullRefPtr&&, Custody& mount_point); KResult unmount(InodeIdentifier guest_inode_id); - KResultOr> open(StringView path, int options, mode_t mode, Custody& base); - KResultOr> create(StringView path, int options, mode_t mode, Custody& parent_custody); + KResultOr> open(StringView path, int options, mode_t mode, Custody& base, Optional = {}); + KResultOr> create(StringView path, int options, mode_t mode, Custody& parent_custody, Optional = {}); KResult mkdir(StringView path, mode_t mode, Custody& base); KResult link(StringView old_path, StringView new_path, Custody& base); KResult unlink(StringView path, Custody& base);