mirror of
https://github.com/RGBCube/serenity
synced 2025-07-02 23:42:13 +00:00
Kernel: Update intermediate nodes when changing unveil permissions
When changing the unveil permissions of a preexisting node, we need to make sure that any intermediate nodes that were created before and should inherit permissions from the updated node are updated properly. This fixes the following bug: unveil("/home/anon/Documents", "r"); unveil("/home", "r"); Now there was a intermediate node for "/home/anon" which still had no permission, even though it should have inherited the permissions from "/home".
This commit is contained in:
parent
1e8006ebb8
commit
2fcebfd6a8
1 changed files with 19 additions and 0 deletions
|
@ -13,6 +13,17 @@
|
|||
|
||||
namespace Kernel {
|
||||
|
||||
static void update_intermediate_node_permissions(UnveilNode& root_node, UnveilAccess new_permissions)
|
||||
{
|
||||
for (auto& entry : root_node.children()) {
|
||||
auto& node = static_cast<UnveilNode&>(*entry.value);
|
||||
if (node.was_explicitly_unveiled())
|
||||
continue;
|
||||
node.set_metadata({ node.path(), new_permissions, node.was_explicitly_unveiled() });
|
||||
update_intermediate_node_permissions(node, new_permissions);
|
||||
}
|
||||
}
|
||||
|
||||
KResultOr<int> Process::sys$unveil(Userspace<const Syscall::SC_unveil_params*> user_params)
|
||||
{
|
||||
Syscall::SC_unveil_params params;
|
||||
|
@ -96,6 +107,14 @@ KResultOr<int> Process::sys$unveil(Userspace<const Syscall::SC_unveil_params*> u
|
|||
if (new_permissions & ~matching_node.permissions())
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
// It is possible that nodes that are "grandchildren" of the matching node have already been unveiled.
|
||||
// This means that there may be intermediate nodes between this one and the unveiled "grandchildren"
|
||||
// that inherited the current node's previous permissions. Those nodes now need their permissions
|
||||
// updated to match the current node.
|
||||
if (matching_node.permissions() != new_permissions)
|
||||
update_intermediate_node_permissions(matching_node, (UnveilAccess)new_permissions);
|
||||
|
||||
matching_node.set_metadata({ matching_node.path(), (UnveilAccess)new_permissions, true });
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue