Kernel: Implement the same hard link protection as Linux

sys$link() will now fail to create hard links in some cases where you
don't own or have write access to the link target.

Work towards #4934
This commit is contained in:
Andreas Kling 2021-01-19 17:59:32 +01:00
parent b1c640a956
commit 9681e3eca0
Notes: sideshowbarker 2024-07-18 23:03:22 +09:00

View File

@ -634,6 +634,23 @@ KResult VFS::chown(StringView path, uid_t a_uid, gid_t a_gid, Custody& base)
return chown(custody, a_uid, a_gid);
}
static bool hard_link_allowed(const Inode& inode)
{
auto metadata = inode.metadata();
if (Process::current()->euid() == metadata.uid)
return true;
if (metadata.is_regular_file()
&& !metadata.is_setuid()
&& !(metadata.is_setgid() && metadata.mode & S_IXGRP)
&& metadata.may_write(*Process::current())) {
return true;
}
return false;
}
KResult VFS::link(StringView old_path, StringView new_path, Custody& base)
{
auto old_custody_or_error = resolve_path(old_path, base);
@ -664,6 +681,9 @@ KResult VFS::link(StringView old_path, StringView new_path, Custody& base)
if (parent_custody->is_readonly())
return KResult(-EROFS);
if (!hard_link_allowed(old_inode))
return KResult(-EPERM);
return parent_inode.add_child(old_inode, LexicalPath(new_path).basename(), old_inode.mode());
}