mirror of
https://github.com/RGBCube/serenity
synced 2025-05-16 19:55:06 +00:00
Kernel: Fix awkward bug where "touch /foo/bar/baz" could create "/baz"
To accomodate file creation, path resolution optionally returns the last valid parent directory seen while traversing the path. Clients will then interpret "ENOENT, but I have a parent for you" as meaning that the file doesn't exist, but its immediate parent directory does. The client then goes ahead and creates a new file. In the case of "/foo/bar/baz" where there is no "/foo", it would fail with ENOENT and "/" as the last seen parent directory, causing e.g the open() syscall to create "/baz". Covered by test_io.
This commit is contained in:
parent
8cc5fa5598
commit
3be1c7b514
1 changed files with 12 additions and 1 deletions
|
@ -692,8 +692,19 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path(StringView path, Custody& ba
|
|||
|
||||
auto& current_parent = custody_chain.last();
|
||||
crumb_id = crumb_inode->lookup(part);
|
||||
if (!crumb_id.is_valid())
|
||||
if (!crumb_id.is_valid()) {
|
||||
if (i != parts.size() - 1) {
|
||||
// We didn't find the filename we were looking for,
|
||||
// and we didn't even reach the last path part.
|
||||
// (ENOENT with non-null parent_custody) signals to caller that
|
||||
// we found the immediate parent of the file, but the file itself
|
||||
// does not exist yet.
|
||||
// Since this is not the immediate parent, clear parent_custody.
|
||||
if (parent_custody)
|
||||
*parent_custody = nullptr;
|
||||
}
|
||||
return KResult(-ENOENT);
|
||||
}
|
||||
if (auto mount = find_mount_for_host(crumb_id))
|
||||
crumb_id = mount->guest();
|
||||
if (inode_was_root_at_head_of_loop && crumb_id.is_root_inode() && !is_vfs_root(crumb_id) && part == "..") {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue