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: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210416172012.8667-1-cccheng@synology.com>
Date:   Sat, 17 Apr 2021 01:20:12 +0800
From:   Chung-Chiang Cheng <shepjeng@...il.com>
To:     christian.brauner@...ntu.com, linux-fsdevel@...r.kernel.org,
        linux-kernel@...r.kernel.org
Cc:     cccheng@...ology.com
Subject: [PATCH] hfsplus: prevent negative dentries when casefolded

hfsplus uses the case-insensitive filenames by default, but VFS negative
dentries are incompatible with case-insensitive. For example, the
following instructions will get a cached filename 'aaa' which isn't
expected. There is no such problem in macOS.

  touch aaa
  rm aaa
  touch AAA

This patch just takes the same approach as ext4 and f2fs to prevent
negative dentries for this issue.

Signed-off-by: Chung-Chiang Cheng <cccheng@...ology.com>
---
 fs/hfsplus/dir.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 03e6c046faf4..fcab8f09b6af 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -121,6 +121,9 @@ static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry,
 	if (S_ISREG(inode->i_mode))
 		HFSPLUS_I(inode)->linkid = linkid;
 out:
+	/* Prevent the negative dentry in the casefolded form from being cached */
+	if (!inode && test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags))
+		return NULL;
 	return d_splice_alias(inode, dentry);
 fail:
 	hfs_find_exit(&fd);
@@ -407,6 +410,12 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry)
 		sbi->file_count--;
 	inode->i_ctime = current_time(inode);
 	mark_inode_dirty(inode);
+
+	/* VFS negative dentries are incompatible with encoding and
+	 * case-insensitiveness
+	 */
+	if (test_bit(HFSPLUS_SB_CASEFOLD, &sbi->flags))
+		d_invalidate(dentry);
 out:
 	mutex_unlock(&sbi->vh_mutex);
 	return res;
@@ -429,6 +438,12 @@ static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry)
 	inode->i_ctime = current_time(inode);
 	hfsplus_delete_inode(inode);
 	mark_inode_dirty(inode);
+
+	/* VFS negative dentries are incompatible with encoding and
+	 * case-insensitiveness
+	 */
+	if (test_bit(HFSPLUS_SB_CASEFOLD, &sbi->flags))
+		d_invalidate(dentry);
 out:
 	mutex_unlock(&sbi->vh_mutex);
 	return res;
-- 
2.25.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ