mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-29 14:14:45 +03:00
Kernel: Allow passing initial UID and GID when creating new inodes
If we're creating something that should have a different owner than the current process's UID/GID, we need to plumb that all the way through VFS down to the FS functions.
This commit is contained in:
parent
82760998a9
commit
4abbedb6e4
Notes:
sideshowbarker
2024-07-19 10:23:46 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/4abbedb6e4b
@ -51,13 +51,13 @@ InodeIdentifier DevPtsFS::root_inode() const
|
||||
return { fsid(), 1 };
|
||||
}
|
||||
|
||||
RefPtr<Inode> DevPtsFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, int& error)
|
||||
RefPtr<Inode> DevPtsFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, uid_t, gid_t, int& error)
|
||||
{
|
||||
error = -EROFS;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<Inode> DevPtsFS::create_directory(InodeIdentifier, const String&, mode_t, int& error)
|
||||
RefPtr<Inode> DevPtsFS::create_directory(InodeIdentifier, const String&, mode_t, uid_t, gid_t, int& error)
|
||||
{
|
||||
error = -EROFS;
|
||||
return nullptr;
|
||||
|
@ -16,8 +16,8 @@ public:
|
||||
virtual const char* class_name() const override { return "DevPtsFS"; }
|
||||
|
||||
virtual InodeIdentifier root_inode() const override;
|
||||
virtual RefPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) override;
|
||||
virtual RefPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) override;
|
||||
virtual RefPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) override;
|
||||
virtual RefPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, uid_t, gid_t, int& error) override;
|
||||
virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
|
||||
|
||||
static void register_slave_pty(SlavePTY&);
|
||||
|
@ -1284,7 +1284,7 @@ bool Ext2FS::set_block_allocation_state(BlockIndex block_index, bool new_state)
|
||||
return true;
|
||||
}
|
||||
|
||||
RefPtr<Inode> Ext2FS::create_directory(InodeIdentifier parent_id, const String& name, mode_t mode, int& error)
|
||||
RefPtr<Inode> 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<Inode> 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<Inode> Ext2FS::create_directory(InodeIdentifier parent_id, const String&
|
||||
return inode;
|
||||
}
|
||||
|
||||
RefPtr<Inode> Ext2FS::create_inode(InodeIdentifier parent_id, const String& name, mode_t mode, off_t size, dev_t dev, int& error)
|
||||
RefPtr<Inode> 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<Inode> 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;
|
||||
|
@ -99,8 +99,8 @@ private:
|
||||
|
||||
virtual const char* class_name() const override;
|
||||
virtual InodeIdentifier root_inode() const override;
|
||||
virtual RefPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) override;
|
||||
virtual RefPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) override;
|
||||
virtual RefPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) override;
|
||||
virtual RefPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, uid_t, gid_t, int& error) override;
|
||||
virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
|
||||
virtual void flush_writes() override;
|
||||
|
||||
|
@ -58,8 +58,8 @@ public:
|
||||
u8 file_type { 0 };
|
||||
};
|
||||
|
||||
virtual RefPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) = 0;
|
||||
virtual RefPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) = 0;
|
||||
virtual RefPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) = 0;
|
||||
virtual RefPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, uid_t, gid_t, int& error) = 0;
|
||||
|
||||
virtual RefPtr<Inode> get_inode(InodeIdentifier) const = 0;
|
||||
|
||||
|
@ -947,13 +947,13 @@ const char* ProcFS::class_name() const
|
||||
return "ProcFS";
|
||||
}
|
||||
|
||||
RefPtr<Inode> ProcFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, int&)
|
||||
RefPtr<Inode> 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<Inode> ProcFS::create_directory(InodeIdentifier, const String&, mode_t, int& error)
|
||||
RefPtr<Inode> ProcFS::create_directory(InodeIdentifier, const String&, mode_t, uid_t, gid_t, int& error)
|
||||
{
|
||||
error = -EROFS;
|
||||
return nullptr;
|
||||
|
@ -23,8 +23,8 @@ public:
|
||||
virtual InodeIdentifier root_inode() const override;
|
||||
virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
|
||||
|
||||
virtual RefPtr<Inode> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, int& error) override;
|
||||
virtual RefPtr<Inode> create_directory(InodeIdentifier parent_id, const String& name, mode_t, int& error) override;
|
||||
virtual RefPtr<Inode> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) override;
|
||||
virtual RefPtr<Inode> create_directory(InodeIdentifier parent_id, const String& name, mode_t, uid_t, gid_t, int& error) override;
|
||||
|
||||
static void add_sys_bool(String&&, Lockable<bool>&, Function<void()>&& notify_callback = nullptr);
|
||||
static void add_sys_string(String&&, Lockable<String>&, Function<void()>&& notify_callback = nullptr);
|
||||
|
@ -62,7 +62,7 @@ RefPtr<Inode> TmpFS::get_inode(InodeIdentifier identifier) const
|
||||
return it->value;
|
||||
}
|
||||
|
||||
RefPtr<Inode> TmpFS::create_inode(InodeIdentifier parent_id, const String& name, mode_t mode, off_t size, dev_t dev, int& error)
|
||||
RefPtr<Inode> 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<Inode> 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<Inode> TmpFS::create_inode(InodeIdentifier parent_id, const String& name,
|
||||
return inode;
|
||||
}
|
||||
|
||||
RefPtr<Inode> TmpFS::create_directory(InodeIdentifier parent_id, const String& name, mode_t mode, int& error)
|
||||
RefPtr<Inode> 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)
|
||||
|
@ -22,8 +22,8 @@ public:
|
||||
virtual InodeIdentifier root_inode() const override;
|
||||
virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
|
||||
|
||||
virtual RefPtr<Inode> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, int& error) override;
|
||||
virtual RefPtr<Inode> create_directory(InodeIdentifier parent_id, const String& name, mode_t, int& error) override;
|
||||
virtual RefPtr<Inode> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t, int& error) override;
|
||||
virtual RefPtr<Inode> create_directory(InodeIdentifier parent_id, const String& name, mode_t, uid_t, gid_t, int& error) override;
|
||||
|
||||
private:
|
||||
TmpFS();
|
||||
|
@ -183,7 +183,7 @@ KResultOr<InodeMetadata> VFS::lookup_metadata(StringView path, Custody& base, in
|
||||
return custody_or_error.value()->inode().metadata();
|
||||
}
|
||||
|
||||
KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options, mode_t mode, Custody& base)
|
||||
KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> owner)
|
||||
{
|
||||
if ((options & O_CREAT) && (options & O_DIRECTORY))
|
||||
return KResult(-EINVAL);
|
||||
@ -196,7 +196,7 @@ KResultOr<NonnullRefPtr<FileDescription>> 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<NonnullRefPtr<FileDescription>> VFS::create(StringView path, int options, mode_t mode, Custody& parent_custody)
|
||||
KResultOr<NonnullRefPtr<FileDescription>> VFS::create(StringView path, int options, mode_t mode, Custody& parent_custody, Optional<UidAndGid> owner)
|
||||
{
|
||||
(void)options;
|
||||
|
||||
@ -285,7 +285,10 @@ KResultOr<NonnullRefPtr<FileDescription>> 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);
|
||||
|
@ -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<FS>&&, Custody& mount_point);
|
||||
KResult unmount(InodeIdentifier guest_inode_id);
|
||||
|
||||
KResultOr<NonnullRefPtr<FileDescription>> open(StringView path, int options, mode_t mode, Custody& base);
|
||||
KResultOr<NonnullRefPtr<FileDescription>> create(StringView path, int options, mode_t mode, Custody& parent_custody);
|
||||
KResultOr<NonnullRefPtr<FileDescription>> open(StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> = {});
|
||||
KResultOr<NonnullRefPtr<FileDescription>> create(StringView path, int options, mode_t mode, Custody& parent_custody, Optional<UidAndGid> = {});
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user