diff --git a/Kernel/FileSystem/Ext2FileSystem.cpp b/Kernel/FileSystem/Ext2FileSystem.cpp index 5efadceb99..a3f5ae00d5 100644 --- a/Kernel/FileSystem/Ext2FileSystem.cpp +++ b/Kernel/FileSystem/Ext2FileSystem.cpp @@ -1333,6 +1333,12 @@ RefPtr Ext2FS::create_inode(InodeIdentifier parent_id, const String& name LOCKER(m_lock); ASSERT(parent_id.fsid() == fsid()); auto parent_inode = get_inode(parent_id); + ASSERT(parent_inode); + + if (static_cast(*parent_inode).m_raw_inode.i_links_count == 0) { + error = -ENOENT; + return nullptr; + } #ifdef EXT2_DEBUG dbgprintf("Ext2FS: Adding inode '%s' (mode %o) to parent directory %u:\n", name.characters(), mode, parent_inode->identifier().index()); @@ -1491,7 +1497,7 @@ int Ext2FSInode::decrement_link_count() return -EROFS; ASSERT(m_raw_inode.i_links_count); --m_raw_inode.i_links_count; - if (m_raw_inode.i_links_count == 0) + if (ref_count() == 1 && m_raw_inode.i_links_count == 0) fs().uncache_inode(index()); set_metadata_dirty(true); return 0; diff --git a/Userland/test_io.cpp b/Userland/test_io.cpp index b34a7e762d..02a7053f27 100644 --- a/Userland/test_io.cpp +++ b/Userland/test_io.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #define EXPECT_ERROR_2(err, syscall, arg1, arg2) \ @@ -208,6 +209,26 @@ void test_eoverflow() close(fd); } +void test_rmdir_while_inside_dir() +{ + int rc = mkdir("/home/anon/testdir", 0700); + ASSERT(rc == 0); + + rc = chdir("/home/anon/testdir"); + ASSERT(rc == 0); + + rc = rmdir("/home/anon/testdir"); + ASSERT(rc == 0); + + int fd = open("x", O_CREAT | O_RDWR, 0600); + if (fd >= 0 || errno != ENOENT) { + fprintf(stderr, "Expected ENOENT when trying to create a file inside a deleted directory. Got %d with errno=%d\n", fd, errno); + } + + rc = chdir("/home/anon"); + ASSERT(rc == 0); +} + int main(int, char**) { int rc; @@ -232,6 +253,7 @@ int main(int, char**) test_open_create_device(); test_unlink_symlink(); test_eoverflow(); + test_rmdir_while_inside_dir(); return 0; }