mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-29 14:14:45 +03:00
Kernel: Implement the same symlink protection as Linux
Path resolution will now refuse to follow symlinks in some cases where you don't own the symlink, or when it's in a sticky world-writable directory and the link has a different owner than the directory. The point of all this is to prevent classic TOCTOU bugs in /tmp etc. Fixes #4934
This commit is contained in:
parent
9681e3eca0
commit
8601108e21
Notes:
sideshowbarker
2024-07-18 23:03:20 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/8601108e211
@ -952,6 +952,21 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path(StringView path, Custody& ba
|
||||
return custody;
|
||||
}
|
||||
|
||||
static bool safe_to_follow_symlink(const Inode& inode, const InodeMetadata& parent_metadata)
|
||||
{
|
||||
auto metadata = inode.metadata();
|
||||
if (Process::current()->euid() == metadata.uid)
|
||||
return true;
|
||||
|
||||
if (!(parent_metadata.is_sticky() && parent_metadata.mode & S_IWOTH))
|
||||
return true;
|
||||
|
||||
if (metadata.uid == parent_metadata.uid)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path_without_veil(StringView path, Custody& base, RefPtr<Custody>* out_parent, int options, int symlink_recursion_level)
|
||||
{
|
||||
if (symlink_recursion_level >= symlink_recursion_limit)
|
||||
@ -1017,6 +1032,10 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path_without_veil(StringView path
|
||||
if (options & O_NOFOLLOW_NOERROR)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!safe_to_follow_symlink(*child_inode, parent_metadata))
|
||||
return KResult(-EACCES);
|
||||
|
||||
auto symlink_target = child_inode->resolve_as_link(parent, out_parent, options, symlink_recursion_level + 1);
|
||||
if (symlink_target.is_error() || !have_more_parts)
|
||||
return symlink_target;
|
||||
|
Loading…
Reference in New Issue
Block a user