lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210328144356.12866-2-andrealmeid@collabora.com>
Date:   Sun, 28 Mar 2021 11:43:54 -0300
From:   André Almeida <andrealmeid@...labora.com>
To:     Alexander Viro <viro@...iv.linux.org.uk>,
        Theodore Ts'o <tytso@....edu>,
        Andreas Dilger <adilger.kernel@...ger.ca>,
        Jaegeuk Kim <jaegeuk@...nel.org>, Chao Yu <chao@...nel.org>
Cc:     krisman@...labora.com, kernel@...labora.com,
        linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
        linux-ext4@...r.kernel.org, linux-f2fs-devel@...ts.sourceforge.net,
        Daniel Rosenberg <drosen@...gle.com>,
        Chao Yu <yuchao0@...wei.com>,
        André Almeida <andrealmeid@...labora.com>
Subject: [PATCH 1/3] fs/dcache: Add d_clear_dir_neg_dentries()

For directories with negative dentries that are becoming case-insensitive
dirs, we need to remove all those negative dentries, otherwise they will
become dangling dentries. During the creation of a new file, if a d_hash
collision happens and the names match in a case-insensitive way, the name
of the file will be the name defined at the negative dentry, that may be
different from the specified by the user. To prevent this from
happening, we need to remove all dentries in a directory. Given that the
directory must be empty before we call this function we are sure that
all dentries there will be negative.

Create a function to remove all negative dentries from a directory, to
be used as explained above by filesystems that support case-insensitive
lookups.

Signed-off-by: André Almeida <andrealmeid@...labora.com>
---
 fs/dcache.c            | 27 +++++++++++++++++++++++++++
 include/linux/dcache.h |  1 +
 2 files changed, 28 insertions(+)

diff --git a/fs/dcache.c b/fs/dcache.c
index 7d24ff7eb206..fafb3016d6fd 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1723,6 +1723,33 @@ void d_invalidate(struct dentry *dentry)
 }
 EXPORT_SYMBOL(d_invalidate);
 
+/**
+ * d_clear_dir_neg_dentries - Remove negative dentries in an inode
+ * @dir: Directory to clear negative dentries
+ *
+ * For directories with negative dentries that are becoming case-insensitive
+ * dirs, we need to remove all those negative dentries, otherwise they will
+ * become dangling dentries. During the creation of a new file, if a d_hash
+ * collision happens and the names match in a case-insensitive, the name of
+ * the file will be the name defined at the negative dentry, that can be
+ * different from the specified by the user. To prevent this from happening, we
+ * need to remove all dentries in a directory. Given that the directory must be
+ * empty before we call this function we are sure that all dentries there will
+ * be negative.
+ */
+void d_clear_dir_neg_dentries(struct inode *dir)
+{
+	struct dentry *alias, *dentry;
+
+	hlist_for_each_entry(alias, &dir->i_dentry, d_u.d_alias) {
+		list_for_each_entry(dentry, &alias->d_subdirs, d_child) {
+			d_drop(dentry);
+			dput(dentry);
+		}
+	}
+}
+EXPORT_SYMBOL(d_clear_dir_neg_dentries);
+
 /**
  * __d_alloc	-	allocate a dcache entry
  * @sb: filesystem it will belong to
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index c1e48014106f..c43cd0be077f 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -250,6 +250,7 @@ extern void shrink_dcache_sb(struct super_block *);
 extern void shrink_dcache_parent(struct dentry *);
 extern void shrink_dcache_for_umount(struct super_block *);
 extern void d_invalidate(struct dentry *);
+extern void d_clear_dir_neg_dentries(struct inode *);
 
 /* only used at mount-time */
 extern struct dentry * d_make_root(struct inode *);
-- 
2.31.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ