From a28f29c82c1967bd017f02aa6ce254335cd48394 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 1 Nov 2020 17:17:23 +0100 Subject: [PATCH] Kernel+LibC: Don't allow a directory to become a subdirectory of itself If you try to do this (e.g "mv directory directory"), sys$rename() will now fail with EDIRINTOSELF. Dr. POSIX says we should return EINVAL for this, but a custom error code allows us to print a much more helpful error message when this problem occurs. :^) --- Kernel/FileSystem/VirtualFileSystem.cpp | 5 +++++ Libraries/LibC/errno_numbers.h | 3 ++- Libraries/LibC/string.cpp | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index c0c93dfecb..54092e91c2 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -522,6 +522,11 @@ KResult VFS::rename(StringView old_path, StringView new_path, Custody& base) if (&old_parent_inode.fs() != &new_parent_inode.fs()) return KResult(-EXDEV); + for (auto* new_ancestor = new_parent_custody.ptr(); new_ancestor; new_ancestor = new_ancestor->parent()) { + if (&old_inode == &new_ancestor->inode()) + return KResult(-EDIRINTOSELF); + } + auto current_process = Process::current(); if (!new_parent_inode.metadata().may_write(*current_process)) return KResult(-EACCES); diff --git a/Libraries/LibC/errno_numbers.h b/Libraries/LibC/errno_numbers.h index 356803b581..fc067b171d 100644 --- a/Libraries/LibC/errno_numbers.h +++ b/Libraries/LibC/errno_numbers.h @@ -99,4 +99,5 @@ #define EPROTO 71 #define ENOTSUP 72 #define EPFNOSUPPORT 73 -#define EMAXERRNO 74 +#define EDIRINTOSELF 74 +#define EMAXERRNO 75 diff --git a/Libraries/LibC/string.cpp b/Libraries/LibC/string.cpp index 5706e6bd30..5bd872d4f8 100644 --- a/Libraries/LibC/string.cpp +++ b/Libraries/LibC/string.cpp @@ -364,6 +364,7 @@ const char* const sys_errlist[] = { "Protocol error", "Not supported", "Protocol family not supported", + "Cannot make directory a subdirectory of itself", "The highest errno +1 :^)", };