From e346331424f98b05f2f0d362e0c291fd88d82aa4 Mon Sep 17 00:00:00 2001 From: Blake Smith Date: Sun, 19 Nov 2023 19:15:37 -0600 Subject: [PATCH] Kernel/FS: Fix check-then-act concurrency bug in FileSystem/Inode When the FileSystem does a sync, it gathers up all the inodes with dirty metadata into a vector. The inode mutex is not held while checking the inode dirty bit, which can lead to a kernel panic due to concurrent inode modifications. Fixes: #21796 --- Kernel/FileSystem/Ext2FS/Inode.cpp | 3 +++ Kernel/FileSystem/Inode.cpp | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Kernel/FileSystem/Ext2FS/Inode.cpp b/Kernel/FileSystem/Ext2FS/Inode.cpp index f0c600c5a3..3029a925f1 100644 --- a/Kernel/FileSystem/Ext2FS/Inode.cpp +++ b/Kernel/FileSystem/Ext2FS/Inode.cpp @@ -494,6 +494,9 @@ InodeMetadata Ext2FSInode::metadata() const ErrorOr Ext2FSInode::flush_metadata() { MutexLocker locker(m_inode_lock); + if (!is_metadata_dirty()) + return {}; + dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::flush_metadata(): Flushing inode", identifier()); TRY(fs().write_ext2_inode(index(), m_raw_inode)); if (is_directory()) { diff --git a/Kernel/FileSystem/Inode.cpp b/Kernel/FileSystem/Inode.cpp index 52b15a4f72..89760dd24c 100644 --- a/Kernel/FileSystem/Inode.cpp +++ b/Kernel/FileSystem/Inode.cpp @@ -39,15 +39,13 @@ void Inode::sync_all() }); for (auto& inode : inodes) { - VERIFY(inode->is_metadata_dirty()); (void)inode->flush_metadata(); } } void Inode::sync() { - if (is_metadata_dirty()) - (void)flush_metadata(); + (void)flush_metadata(); auto result = fs().flush_writes(); if (result.is_error()) { // TODO: Figure out how to propagate error to a higher function.