Skip to content

Commit

Permalink
Kernel: Resolve relative paths when there is a veil (SerenityOS#1474)
Browse files Browse the repository at this point in the history
  • Loading branch information
muscar authored and nimelehin committed Apr 12, 2020
1 parent c6f8587 commit 1d4f857
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
14 changes: 12 additions & 2 deletions Kernel/FileSystem/VirtualFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -768,10 +768,20 @@ KResult VFS::validate_path_against_process_veil(StringView path, int options)

KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path(StringView path, Custody& base, RefPtr<Custody>* out_parent, int options, int symlink_recursion_level)
{
auto result = validate_path_against_process_veil(path, options);
auto custody_or_error = resolve_path_without_veil(path, base, out_parent, options, symlink_recursion_level);
if (custody_or_error.is_error())
return custody_or_error.error();

auto& custody = custody_or_error.value();
auto result = validate_path_against_process_veil(custody->absolute_path(), options);
if (result.is_error())
return result;

return custody;
}

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)
return KResult(-ELOOP);

Expand Down Expand Up @@ -845,7 +855,7 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path(StringView path, Custody& ba
remaining_path.append('.');
remaining_path.append(path.substring_view_starting_after_substring(part));

return resolve_path(remaining_path.to_string(), *symlink_target.value(), out_parent, options, symlink_recursion_level + 1);
return resolve_path_without_veil(remaining_path.to_string(), *symlink_target.value(), out_parent, options, symlink_recursion_level + 1);
}
}

Expand Down
1 change: 1 addition & 0 deletions Kernel/FileSystem/VirtualFileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class VFS {

Custody& root_custody();
KResultOr<NonnullRefPtr<Custody>> resolve_path(StringView path, Custody& base, RefPtr<Custody>* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0);
KResultOr<NonnullRefPtr<Custody>> resolve_path_without_veil(StringView path, Custody& base, RefPtr<Custody>* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0);

private:
friend class FileDescription;
Expand Down
12 changes: 10 additions & 2 deletions Kernel/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4772,6 +4772,14 @@ int Process::sys$unveil(const Syscall::SC_unveil_params* user_params)
if (path.value().is_empty() || path.value().characters()[0] != '/')
return -EINVAL;

auto custody_or_error = VFS::the().resolve_path_without_veil(path.value(), root_directory());
if (custody_or_error.is_error())
// FIXME Should this be EINVAL?
return custody_or_error.error();

auto& custody = custody_or_error.value();
auto new_unveiled_path = custody->absolute_path();

auto permissions = validate_and_copy_string_from_user(params.permissions);
if (permissions.is_null())
return -EFAULT;
Expand All @@ -4798,15 +4806,15 @@ int Process::sys$unveil(const Syscall::SC_unveil_params* user_params)

for (size_t i = 0; i < m_unveiled_paths.size(); ++i) {
auto& unveiled_path = m_unveiled_paths[i];
if (unveiled_path.path == path.value()) {
if (unveiled_path.path == new_unveiled_path) {
if (new_permissions & ~unveiled_path.permissions)
return -EPERM;
unveiled_path.permissions = new_permissions;
return 0;
}
}

m_unveiled_paths.append({ path.value(), new_permissions });
m_unveiled_paths.append({ new_unveiled_path, new_permissions });
ASSERT(m_veil_state != VeilState::Locked);
m_veil_state = VeilState::Dropped;
return 0;
Expand Down

0 comments on commit 1d4f857

Please sign in to comment.