diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2020-12-26 17:54:01 +0330 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-26 16:10:04 +0100 |
commit | 7b5aa06702a3e9ddca318a95a0921cb5b3537e9d (patch) | |
tree | 21b2d5a0bef9877fdf11727df4117b1e49621ee9 /Kernel/Syscalls/unveil.cpp | |
parent | 3be9a9ac7630ffdecd8bf2bfb741e2b92550507d (diff) | |
download | serenity-7b5aa06702a3e9ddca318a95a0921cb5b3537e9d.zip |
Kernel: Allow 'elevating' unveil permissions if implicitly inherited from '/'
This can happen when an unveil follows another with a path that is a
sub-path of the other one:
```c++
unveil("/home/anon/.config/whoa.ini", "rw");
unveil("/home/anon", "r"); // this would fail, as "/home/anon" inherits
// the permissions of "/", which is None.
```
Diffstat (limited to 'Kernel/Syscalls/unveil.cpp')
-rw-r--r-- | Kernel/Syscalls/unveil.cpp | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/Kernel/Syscalls/unveil.cpp b/Kernel/Syscalls/unveil.cpp index 74f75252c5..8657ecfee0 100644 --- a/Kernel/Syscalls/unveil.cpp +++ b/Kernel/Syscalls/unveil.cpp @@ -109,9 +109,14 @@ int Process::sys$unveil(Userspace<const Syscall::SC_unveil_params*> user_params) auto it = lexical_path.parts().begin(); auto& matching_node = m_unveiled_paths.traverse_until_last_accessible_node(it, lexical_path.parts().end()); if (it.is_end()) { - if (new_permissions & ~matching_node.permissions()) - return -EPERM; - matching_node.set_metadata({ matching_node.path(), (UnveilAccess)new_permissions, true }); + auto old_permissions = matching_node.permissions(); + // Allow "elevating" the permissions when the permissions are inherited from root (/), + // as that would be the first time this path is unveiled. + if (old_permissions != UnveilAccess::None || !matching_node.permissions_inherited_from_root()) { + if (new_permissions & ~old_permissions) + return -EPERM; + } + matching_node.set_metadata({ matching_node.path(), (UnveilAccess)new_permissions, true, false }); return 0; } @@ -119,7 +124,7 @@ int Process::sys$unveil(Userspace<const Syscall::SC_unveil_params*> user_params) it, lexical_path.parts().end(), { new_unveiled_path, (UnveilAccess)new_permissions, true }, - [](auto& parent, auto& it) -> Optional<UnveilMetadata> { return UnveilMetadata { String::formatted("{}/{}", parent.path(), *it), parent.permissions(), false }; }); + [](auto& parent, auto& it) -> Optional<UnveilMetadata> { return UnveilMetadata { String::formatted("{}/{}", parent.path(), *it), parent.permissions(), false, parent.permissions_inherited_from_root() }; }); ASSERT(m_veil_state != VeilState::Locked); m_veil_state = VeilState::Dropped; return 0; |