1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-21 15:35:07 +00:00

Kernel/FileSystem: Prevent symlink creation in veiled directory paths

Also, try to resolve the target path and check if it is allowed to be
accessed under the unveil rules.
This commit is contained in:
Liav A 2022-12-17 07:55:38 +02:00 committed by Sam Atkins
parent 1c630316ec
commit 2e710de2f4

View file

@ -798,12 +798,25 @@ ErrorOr<void> VirtualFileSystem::unlink(Credentials const& credentials, StringVi
ErrorOr<void> VirtualFileSystem::symlink(Credentials const& credentials, StringView target, StringView linkpath, Custody& base)
{
// NOTE: Check that the actual target (if it exists right now) is unveiled and prevent creating symlinks on veiled paths!
if (auto target_custody_or_error = resolve_path_without_veil(credentials, target, base, nullptr, O_RDWR, 0); !target_custody_or_error.is_error()) {
auto target_custody = target_custody_or_error.release_value();
TRY(validate_path_against_process_veil(*target_custody, O_RDWR));
}
RefPtr<Custody> parent_custody;
auto existing_custody_or_error = resolve_path(credentials, linkpath, base, &parent_custody);
auto existing_custody_or_error = resolve_path(credentials, linkpath, base, &parent_custody, O_RDWR);
if (!existing_custody_or_error.is_error())
return EEXIST;
if (!parent_custody)
return ENOENT;
// NOTE: VERY IMPORTANT! We prevent creating symlinks in case the program didn't unveil the parent_custody
// path! For example, say the program wanted to create a symlink in /tmp/symlink to /tmp/test/pointee_symlink
// and unveiled the /tmp/test/ directory path beforehand, but not the /tmp directory path - the symlink syscall will
// fail here because we can't create the symlink in a parent directory path we didn't unveil beforehand.
TRY(validate_path_against_process_veil(*parent_custody, O_RDWR));
if (existing_custody_or_error.is_error() && existing_custody_or_error.error().code() != ENOENT)
return existing_custody_or_error.release_error();
auto& parent_inode = parent_custody->inode();