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: <20220607024942.811-1-frank.li@vivo.com>
Date:   Tue,  7 Jun 2022 10:49:42 +0800
From:   Yangtao Li <frank.li@...o.com>
To:     linkinjeon@...nel.org, sj1557.seo@...sung.com
Cc:     linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
        Yangtao Li <frank.li@...o.com>
Subject: [PATCH] exfat: intorduce skip_stream_check mount opt

There are some files in my USB flash drive that can be recognized by
the Windows computer, but on Linux, only the existence of the file name
can be seen.

When executing ls command to view the file attributes or access, the file
does not exist. Therefore, when the current windows and linux drivers
access a file, there is a difference in the checking of the file metadata,
which leads to this situation.
(There is also a difference between traversing all children of the parent
directory and finding a child in the parent directory on linux.)

So, we introduce a new mount option that skips the check of the file stream
entry in exfat_find_dir_entry().

Signed-off-by: Yangtao Li <frank.li@...o.com>
---
 fs/exfat/dir.c      | 6 ++++--
 fs/exfat/exfat_fs.h | 3 ++-
 fs/exfat/super.c    | 7 +++++++
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index cb1c0d8c1714..4ea0077f2955 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -1013,6 +1013,7 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
 			}
 
 			if (entry_type == TYPE_STREAM) {
+				struct exfat_mount_options *opts = &sbi->options;
 				u16 name_hash;
 
 				if (step != DIRENT_STEP_STRM) {
@@ -1023,9 +1024,10 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
 				step = DIRENT_STEP_FILE;
 				name_hash = le16_to_cpu(
 						ep->dentry.stream.name_hash);
-				if (p_uniname->name_hash == name_hash &&
+				if ((p_uniname->name_hash == name_hash &&
 				    p_uniname->name_len ==
-						ep->dentry.stream.name_len) {
+						ep->dentry.stream.name_len) ||
+					opts->skip_stream_check == 1) {
 					step = DIRENT_STEP_NAME;
 					order = 1;
 					name_len = 0;
diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
index 1d6da61157c9..5cd00ac112d9 100644
--- a/fs/exfat/exfat_fs.h
+++ b/fs/exfat/exfat_fs.h
@@ -204,7 +204,8 @@ struct exfat_mount_options {
 	/* on error: continue, panic, remount-ro */
 	enum exfat_error_mode errors;
 	unsigned utf8:1, /* Use of UTF-8 character set */
-		 discard:1; /* Issue discard requests on deletions */
+		 discard:1, /* Issue discard requests on deletions */
+		 skip_stream_check:1; /* Skip stream entry check in exfat_find_dir_entry() */
 	int time_offset; /* Offset of timestamps from UTC (in minutes) */
 };
 
diff --git a/fs/exfat/super.c b/fs/exfat/super.c
index 5539ffc20d16..e9c7df25f2b5 100644
--- a/fs/exfat/super.c
+++ b/fs/exfat/super.c
@@ -173,6 +173,8 @@ static int exfat_show_options(struct seq_file *m, struct dentry *root)
 		seq_puts(m, ",errors=remount-ro");
 	if (opts->discard)
 		seq_puts(m, ",discard");
+	if (opts->skip_stream_check)
+		seq_puts(m, ",skip_stream_check");
 	if (opts->time_offset)
 		seq_printf(m, ",time_offset=%d", opts->time_offset);
 	return 0;
@@ -216,6 +218,7 @@ enum {
 	Opt_charset,
 	Opt_errors,
 	Opt_discard,
+	Opt_skip_stream_check,
 	Opt_time_offset,
 
 	/* Deprecated options */
@@ -242,6 +245,7 @@ static const struct fs_parameter_spec exfat_parameters[] = {
 	fsparam_string("iocharset",		Opt_charset),
 	fsparam_enum("errors",			Opt_errors, exfat_param_enums),
 	fsparam_flag("discard",			Opt_discard),
+	fsparam_flag("skip_stream_check",	Opt_skip_stream_check),
 	fsparam_s32("time_offset",		Opt_time_offset),
 	__fsparam(NULL, "utf8",			Opt_utf8, fs_param_deprecated,
 		  NULL),
@@ -296,6 +300,9 @@ static int exfat_parse_param(struct fs_context *fc, struct fs_parameter *param)
 	case Opt_discard:
 		opts->discard = 1;
 		break;
+	case Opt_skip_stream_check:
+		opts->skip_stream_check = 1;
+		break;
 	case Opt_time_offset:
 		/*
 		 * Make the limit 24 just in case someone invents something
-- 
2.35.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ