From ae8558dd5c278199f5c2c3fbb680a42e9a349efa Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 17 Aug 2022 20:13:44 +0200 Subject: [PATCH] Kernel: Don't do path resolution in sys$chdir() while holding spinlock Path resolution may do blocking I/O so we must not do it while holding a spinlock. There are tons of problems like this throughout the kernel and we need to find and fix all of them. --- Kernel/Syscalls/chdir.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Kernel/Syscalls/chdir.cpp b/Kernel/Syscalls/chdir.cpp index 001aa661c2..852392358b 100644 --- a/Kernel/Syscalls/chdir.cpp +++ b/Kernel/Syscalls/chdir.cpp @@ -15,10 +15,15 @@ ErrorOr Process::sys$chdir(Userspace user_path, size_t pat VERIFY_NO_PROCESS_BIG_LOCK(this); TRY(require_promise(Pledge::rpath)); auto path = TRY(get_syscall_path_argument(user_path, path_length)); - return m_current_directory.with([&](auto& current_directory) -> ErrorOr { - current_directory = TRY(VirtualFileSystem::the().open_directory(path->view(), *current_directory)); - return 0; + auto current_directory = m_current_directory.with([](auto& current_directory) -> NonnullRefPtr { + return *current_directory; }); + RefPtr new_directory = TRY(VirtualFileSystem::the().open_directory(path->view(), *current_directory)); + m_current_directory.with([&](auto& current_directory) { + // NOTE: We use swap() here to avoid manipulating the ref counts while holding the lock. + swap(current_directory, new_directory); + }); + return 0; } ErrorOr Process::sys$fchdir(int fd)