mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 04:17:35 +00:00
Kernel: Resolve relative paths when there is a veil (#1474)
This commit is contained in:
parent
6d26714ded
commit
d013753f83
3 changed files with 23 additions and 4 deletions
|
@ -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)
|
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())
|
if (result.is_error())
|
||||||
return result;
|
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)
|
if (symlink_recursion_level >= symlink_recursion_limit)
|
||||||
return KResult(-ELOOP);
|
return KResult(-ELOOP);
|
||||||
|
|
||||||
|
@ -845,7 +855,7 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path(StringView path, Custody& ba
|
||||||
remaining_path.append('.');
|
remaining_path.append('.');
|
||||||
remaining_path.append(path.substring_view_starting_after_substring(part));
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,7 @@ public:
|
||||||
|
|
||||||
Custody& root_custody();
|
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(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:
|
private:
|
||||||
friend class FileDescription;
|
friend class FileDescription;
|
||||||
|
|
|
@ -4772,6 +4772,14 @@ int Process::sys$unveil(const Syscall::SC_unveil_params* user_params)
|
||||||
if (path.value().is_empty() || path.value().characters()[0] != '/')
|
if (path.value().is_empty() || path.value().characters()[0] != '/')
|
||||||
return -EINVAL;
|
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);
|
auto permissions = validate_and_copy_string_from_user(params.permissions);
|
||||||
if (permissions.is_null())
|
if (permissions.is_null())
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -4798,7 +4806,7 @@ int Process::sys$unveil(const Syscall::SC_unveil_params* user_params)
|
||||||
|
|
||||||
for (size_t i = 0; i < m_unveiled_paths.size(); ++i) {
|
for (size_t i = 0; i < m_unveiled_paths.size(); ++i) {
|
||||||
auto& unveiled_path = m_unveiled_paths[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)
|
if (new_permissions & ~unveiled_path.permissions)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
unveiled_path.permissions = new_permissions;
|
unveiled_path.permissions = new_permissions;
|
||||||
|
@ -4806,7 +4814,7 @@ int Process::sys$unveil(const Syscall::SC_unveil_params* user_params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_unveiled_paths.append({ path.value(), new_permissions });
|
m_unveiled_paths.append({ new_unveiled_path, new_permissions });
|
||||||
ASSERT(m_veil_state != VeilState::Locked);
|
ASSERT(m_veil_state != VeilState::Locked);
|
||||||
m_veil_state = VeilState::Dropped;
|
m_veil_state = VeilState::Dropped;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue