summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2020-01-10 12:51:05 +0100
committerAndreas Kling <awesomekling@gmail.com>2020-01-10 14:07:36 +0100
commitb1ffde61995d83d0f5cd5c860f6353a0e5e61399 (patch)
treec75a77d1862e44a4e55e1a734cdeda9645997dfe
parentf026f0f4bb42b1d77e2ad9f1c55e5f729a668f6d (diff)
downloadserenity-b1ffde61995d83d0f5cd5c860f6353a0e5e61399.zip
Kernel: unlink() should not follow symlinks
-rw-r--r--Kernel/FileSystem/VirtualFileSystem.cpp2
-rw-r--r--Userland/test_io.cpp15
2 files changed, 16 insertions, 1 deletions
diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp
index 0c14abb888..28276e655d 100644
--- a/Kernel/FileSystem/VirtualFileSystem.cpp
+++ b/Kernel/FileSystem/VirtualFileSystem.cpp
@@ -518,7 +518,7 @@ KResult VFS::link(StringView old_path, StringView new_path, Custody& base)
KResult VFS::unlink(StringView path, Custody& base)
{
RefPtr<Custody> parent_custody;
- auto custody_or_error = resolve_path(path, base, &parent_custody);
+ auto custody_or_error = resolve_path(path, base, &parent_custody, O_NOFOLLOW_NOERROR);
if (custody_or_error.is_error())
return custody_or_error.error();
auto& custody = *custody_or_error.value();
diff --git a/Userland/test_io.cpp b/Userland/test_io.cpp
index b85aeac7a7..2d2982f626 100644
--- a/Userland/test_io.cpp
+++ b/Userland/test_io.cpp
@@ -174,6 +174,20 @@ void test_open_create_device()
close(fd);
}
+void test_unlink_symlink()
+{
+ int rc = symlink("/proc/2/foo", "/tmp/linky");
+ if (rc < 0) {
+ perror("symlink");
+ ASSERT_NOT_REACHED();
+ }
+ rc = unlink("/tmp/linky");
+ if (rc < 0) {
+ perror("unlink");
+ fprintf(stderr, "Expected unlink() of a symlink into an unreadable directory to succeed!\n");
+ }
+}
+
int main(int, char**)
{
int rc;
@@ -196,6 +210,7 @@ int main(int, char**)
test_tmpfs_read_past_end();
test_procfs_read_past_end();
test_open_create_device();
+ test_unlink_symlink();
return 0;
}