From: "Darrick J. Wong" <djwong@kernel.org>
To: cem@kernel.org
Cc: linux-xfs@vger.kernel.org, david@fromorbit.com, hch@infradead.org
Subject: [PATCH v2 3/5] xfs_db: fix metadump name obfuscation for ascii-ci filesystems
Date: Thu, 15 Jun 2023 09:11:04 -0700 [thread overview]
Message-ID: <20230615161104.GP11441@frogsfrogsfrogs> (raw)
In-Reply-To: <168597940416.1226098.14610650380180437820.stgit@frogsfrogsfrogs>
From: Darrick J. Wong <djwong@kernel.org>
Now that we've stabilized the dirent hash function for ascii-ci
filesystems, adapt the metadump name obfuscation code to detect when
it's obfuscating a directory entry name on an ascii-ci filesystem and
spit out names that actually have the same hash.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
v2: s/alloca/malloc/
---
db/metadump.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 73 insertions(+), 9 deletions(-)
diff --git a/db/metadump.c b/db/metadump.c
index 317ff72802d..9ccee0b7ace 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -817,13 +817,17 @@ static void
obfuscate_name(
xfs_dahash_t hash,
size_t name_len,
- unsigned char *name)
+ unsigned char *name,
+ bool is_dirent)
{
- unsigned char *newp = name;
+ unsigned char *oldname = NULL;
+ unsigned char *newp;
int i;
- xfs_dahash_t new_hash = 0;
+ xfs_dahash_t new_hash;
unsigned char *first;
unsigned char high_bit;
+ int tries = 0;
+ bool is_ci_name = is_dirent && xfs_has_asciici(mp);
int shift;
/*
@@ -836,6 +840,26 @@ obfuscate_name(
if (name_len < 5)
return;
+ if (is_ci_name) {
+ oldname = malloc(name_len);
+ if (!oldname)
+ return;
+ memcpy(oldname, name, name_len);
+ }
+
+again:
+ newp = name;
+ new_hash = 0;
+
+ /*
+ * If we cannot generate a ci-compatible obfuscated name after 1000
+ * tries, don't bother obfuscating the name.
+ */
+ if (tries++ > 1000) {
+ memcpy(name, oldname, name_len);
+ goto out_free;
+ }
+
/*
* The beginning of the obfuscated name can be pretty much
* anything, so fill it in with random characters.
@@ -843,7 +867,11 @@ obfuscate_name(
*/
for (i = 0; i < name_len - 5; i++) {
*newp = random_filename_char();
- new_hash = *newp ^ rol32(new_hash, 7);
+ if (is_ci_name)
+ new_hash = xfs_ascii_ci_xfrm(*newp) ^
+ rol32(new_hash, 7);
+ else
+ new_hash = *newp ^ rol32(new_hash, 7);
newp++;
}
@@ -867,6 +895,17 @@ obfuscate_name(
high_bit = 0x80;
} else
high_bit = 0;
+
+ /*
+ * If ascii-ci is enabled, uppercase characters are converted
+ * to lowercase characters while computing the name hash. If
+ * any of the necessary correction bytes are uppercase, the
+ * hash of the new name will not match. Try again with a
+ * different prefix.
+ */
+ if (is_ci_name && xfs_ascii_ci_need_xfrm(*newp))
+ goto again;
+
ASSERT(!is_invalid_char(*newp));
newp++;
}
@@ -880,8 +919,15 @@ obfuscate_name(
*/
if (high_bit) {
*first ^= 0x10;
+
+ if (is_ci_name && xfs_ascii_ci_need_xfrm(*first))
+ goto again;
+
ASSERT(!is_invalid_char(*first));
}
+
+out_free:
+ free(oldname);
}
/*
@@ -1177,6 +1223,24 @@ handle_duplicate_name(xfs_dahash_t hash, size_t name_len, unsigned char *name)
return 1;
}
+static inline xfs_dahash_t
+dirattr_hashname(
+ bool is_dirent,
+ const uint8_t *name,
+ int namelen)
+{
+ if (is_dirent) {
+ struct xfs_name xname = {
+ .name = name,
+ .len = namelen,
+ };
+
+ return libxfs_dir2_hashname(mp, &xname);
+ }
+
+ return libxfs_da_hashname(name, namelen);
+}
+
static void
generate_obfuscated_name(
xfs_ino_t ino,
@@ -1205,9 +1269,9 @@ generate_obfuscated_name(
/* Obfuscate the name (if possible) */
- hash = libxfs_da_hashname(name, namelen);
- obfuscate_name(hash, namelen, name);
- ASSERT(hash == libxfs_da_hashname(name, namelen));
+ hash = dirattr_hashname(ino != 0, name, namelen);
+ obfuscate_name(hash, namelen, name, ino != 0);
+ ASSERT(hash == dirattr_hashname(ino != 0, name, namelen));
/*
* Make sure the name is not something already seen. If we
@@ -1320,7 +1384,7 @@ obfuscate_path_components(
/* last (or single) component */
namelen = strnlen((char *)comp, len);
hash = libxfs_da_hashname(comp, namelen);
- obfuscate_name(hash, namelen, comp);
+ obfuscate_name(hash, namelen, comp, false);
ASSERT(hash == libxfs_da_hashname(comp, namelen));
break;
}
@@ -1332,7 +1396,7 @@ obfuscate_path_components(
continue;
}
hash = libxfs_da_hashname(comp, namelen);
- obfuscate_name(hash, namelen, comp);
+ obfuscate_name(hash, namelen, comp, false);
ASSERT(hash == libxfs_da_hashname(comp, namelen));
comp += namelen + 1;
len -= namelen + 1;
next prev parent reply other threads:[~2023-06-15 16:11 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-05 15:36 [PATCHSET v3 0/5] xfsprogs: fix ascii-ci problems, then kill it Darrick J. Wong
2023-06-05 15:36 ` [PATCH 1/5] libxfs: test the ascii case-insensitive hash Darrick J. Wong
2023-06-05 16:30 ` Eric Sandeen
2023-06-14 7:44 ` Carlos Maiolino
2023-06-05 15:36 ` [PATCH 2/5] xfs_db: move obfuscate_name assertion to callers Darrick J. Wong
2023-06-05 15:36 ` [PATCH 3/5] xfs_db: fix metadump name obfuscation for ascii-ci filesystems Darrick J. Wong
2023-06-05 16:59 ` Eric Sandeen
2023-06-05 17:09 ` Darrick J. Wong
2023-06-05 17:18 ` Eric Sandeen
2023-06-05 17:19 ` Eric Sandeen
2023-06-14 11:10 ` Carlos Maiolino
2023-06-15 16:11 ` Darrick J. Wong [this message]
2023-06-22 11:45 ` [PATCH v2 " Carlos Maiolino
2023-06-05 15:36 ` [PATCH 4/5] mkfs.xfs.8: warn about the version=ci feature Darrick J. Wong
2023-06-05 15:36 ` [PATCH 5/5] mkfs: deprecate the ascii-ci feature Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230615161104.GP11441@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=cem@kernel.org \
--cc=david@fromorbit.com \
--cc=hch@infradead.org \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox