summaryrefslogtreecommitdiff
path: root/Kernel/Syscalls/unveil.cpp
diff options
context:
space:
mode:
authorAnotherTest <ali.mpfard@gmail.com>2020-12-26 13:54:34 +0330
committerAndreas Kling <kling@serenityos.org>2020-12-26 11:54:54 +0100
commita9184fcb76d01304bdf3b206d52d315ce52e28ac (patch)
treeb5534842a9cbc1654ad0cf9d9dab2ccc197d02e3 /Kernel/Syscalls/unveil.cpp
parentcb3348191b1672afbfc99939cce4bc6f2b63eb4a (diff)
downloadserenity-a9184fcb76d01304bdf3b206d52d315ce52e28ac.zip
Kernel: Implement unveil() as a prefix-tree
Fixes #4530.
Diffstat (limited to 'Kernel/Syscalls/unveil.cpp')
-rw-r--r--Kernel/Syscalls/unveil.cpp33
1 files changed, 19 insertions, 14 deletions
diff --git a/Kernel/Syscalls/unveil.cpp b/Kernel/Syscalls/unveil.cpp
index 57807cd8e9..74f75252c5 100644
--- a/Kernel/Syscalls/unveil.cpp
+++ b/Kernel/Syscalls/unveil.cpp
@@ -68,19 +68,19 @@ int Process::sys$unveil(Userspace<const Syscall::SC_unveil_params*> user_params)
for (const char permission : permissions) {
switch (permission) {
case 'r':
- new_permissions |= UnveiledPath::Access::Read;
+ new_permissions |= UnveilAccess::Read;
break;
case 'w':
- new_permissions |= UnveiledPath::Access::Write;
+ new_permissions |= UnveilAccess::Write;
break;
case 'x':
- new_permissions |= UnveiledPath::Access::Execute;
+ new_permissions |= UnveilAccess::Execute;
break;
case 'c':
- new_permissions |= UnveiledPath::Access::CreateOrRemove;
+ new_permissions |= UnveilAccess::CreateOrRemove;
break;
case 'b':
- new_permissions |= UnveiledPath::Access::Browse;
+ new_permissions |= UnveilAccess::Browse;
break;
default:
return -EINVAL;
@@ -97,7 +97,7 @@ int Process::sys$unveil(Userspace<const Syscall::SC_unveil_params*> user_params)
auto custody_or_error = VFS::the().resolve_path_without_veil(path.value(), root_directory(), &parent_custody);
if (!custody_or_error.is_error()) {
new_unveiled_path = custody_or_error.value()->absolute_path();
- } else if (custody_or_error.error() == -ENOENT && parent_custody && (new_permissions & UnveiledPath::Access::CreateOrRemove)) {
+ } else if (custody_or_error.error() == -ENOENT && parent_custody && (new_permissions & UnveilAccess::CreateOrRemove)) {
String basename = LexicalPath(path.value()).basename();
new_unveiled_path = String::formatted("{}/{}", parent_custody->absolute_path(), basename);
} else {
@@ -105,16 +105,21 @@ int Process::sys$unveil(Userspace<const Syscall::SC_unveil_params*> user_params)
return custody_or_error.error();
}
- for (auto& unveiled_path : m_unveiled_paths) {
- if (unveiled_path.path == new_unveiled_path) {
- if (new_permissions & ~unveiled_path.permissions)
- return -EPERM;
- unveiled_path.permissions = new_permissions;
- return 0;
- }
+ LexicalPath lexical_path(new_unveiled_path);
+ 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 });
+ return 0;
}
- m_unveiled_paths.append({ new_unveiled_path, new_permissions });
+ matching_node.insert(
+ 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 }; });
ASSERT(m_veil_state != VeilState::Locked);
m_veil_state = VeilState::Dropped;
return 0;