[PATCH v3, 11/16] xfsprogs: metadump: move obfuscation algorithm into its own function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Pull the name obfuscation algorithm into a separate function.
This separates it from the checking for duplicates and recording
of names that are found to be acceptable.

Signed-off-by: Alex Elder <aelder@xxxxxxx>

This is a new change, not posted with this series previously.

---
 db/metadump.c |  146 +++++++++++++++++++++++++++++++---------------------------
 1 file changed, 80 insertions(+), 66 deletions(-)

Index: b/db/metadump.c
===================================================================
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -468,6 +468,85 @@ in_lost_found(
 	return slen == namelen && !memcmp(name, s, namelen);
 }
 
+/*
+ * Given a name and its hash value, massage the name in such a way
+ * that the result is another name of equal length which shares the
+ * same hash value.
+ */
+static void
+obfuscate_name(
+	xfs_dahash_t	hash,
+	size_t		name_len,
+	uchar_t		*name)
+{
+	uchar_t		newname[NAME_MAX];
+	uchar_t		*newp = newname;
+	int		i;
+	xfs_dahash_t	new_hash = 0;
+	uchar_t		*first;
+	uchar_t		high_bit;
+	int		shift;
+
+	/*
+	 * Our obfuscation algorithm requires at least 5-character
+	 * names, so don't bother if the name is too short.
+	 */
+	if (name_len < 5)
+	    	return;
+
+	/*
+	 * The beginning of the obfuscated name can be pretty much
+	 * anything, so fill it in with random characters.
+	 * Accumulate its new hash value as we go.
+	 */
+	for (i = 0; i < name_len - 5; i++) {
+		*newp = random_filename_char();
+		new_hash = *newp ^ rol32(new_hash, 7);
+		newp++;
+	}
+
+	/*
+	 * Compute which five bytes need to be used at the end of
+	 * the name so the hash of the obfuscated name is the same
+	 * as the hash of the original.  If any result in an invalid
+	 * character, flip a bit and arrange for a corresponding bit
+	 * in a neighboring byte to be flipped as well.  For the
+	 * last byte, the "neighbor" to change is the first byte
+	 * we're computing here.
+	 */
+	new_hash = rol32(new_hash, 3) ^ hash;
+
+	first = newp;
+	high_bit = 0;
+	for (shift = 28; shift >= 0; shift -= 7) {
+		*newp = (new_hash >> shift & 0x7f) ^ high_bit;
+		if (is_invalid_char(*newp)) {
+			*newp ^= 1;
+			high_bit = 0x80;
+		} else
+			high_bit = 0;
+		ASSERT(!is_invalid_char(*newp));
+		newp++;
+	}
+
+	/*
+	 * If we flipped a bit on the last byte, we need to fix up
+	 * the matching bit in the first byte.  The result will
+	 * be a valid character, because we know that first byte
+	 * has 0's in its upper four bits (it was produced by a
+	 * 28-bit right-shift of a 32-bit unsigned value).
+	 */
+	if (high_bit) {
+		*first ^= 0x10;
+		ASSERT(!is_invalid_char(*first));
+	}
+	ASSERT(libxfs_da_hashname(newname, name_len) == hash);
+
+	/* Copy the fully obfuscated name back to the caller's buffer */
+
+	memcpy(name, newname, name_len);
+}
+
 static void
 generate_obfuscated_name(
 	xfs_ino_t		ino,
@@ -480,13 +559,6 @@ generate_obfuscated_name(
 	uchar_t			*newp;
 
 	/*
-	 * Our obfuscation algorithm requires at least 5-character
-	 * names, so don't bother if the name is too short.
-	 */
-	if (namelen < 5)
-	    	return;
-
-	/*
 	 * We don't obfuscate "lost+found" or any orphan files
 	 * therein.  When the name table is used for extended
 	 * attributes, the inode number provided is 0, in which
@@ -508,65 +580,7 @@ generate_obfuscated_name(
 
 	hash = libxfs_da_hashname(name, namelen);
 	do {
-		int		i;
-		xfs_dahash_t	newhash = 0;
-		uchar_t		*first;
-		uchar_t		high_bit;
-		int		shift;
-
-		/*
-		 * The beginning of the obfuscated name can be
-		 * pretty much anything, so fill it in with random
-		 * characters.  Accumulate its new hash value as we
-		 * go.
-		 */
-		newp = &newname[0];
-		for (i = 0; i < namelen - 5; i++) {
-			*newp = random_filename_char();
-			newhash = *newp ^ rol32(newhash, 7);
-			newp++;
-		}
-
-		/*
-		 * Compute which five bytes need to be used at the
-		 * end of the name so the hash of the obfuscated
-		 * name is the same as the hash of the original.  If
-		 * any result in an invalid character, flip a bit
-		 * and arrange for a corresponding bit in a
-		 * neighboring byte to be flipped as well.  For the
-		 * last byte, the "neighbor" to change is the first
-		 * byte we're computing here.
-		 */
-		newhash = rol32(newhash, 3) ^ hash;
-
-		first = newp;
-		high_bit = 0;
-		for (shift = 28; shift >= 0; shift -= 7) {
-			*newp = (newhash >> shift & 0x7f) ^ high_bit;
-			if (is_invalid_char(*newp)) {
-				*newp ^= 1;
-				high_bit = 0x80;
-			} else
-				high_bit = 0;
-			ASSERT(!is_invalid_char(*newp));
-			newp++;
-		}
-
-		/*
-		 * If we flipped a bit on the last byte, we need to
-		 * fix up the first one we computed.
-		 *
-		 * That first byte had 0's in its upper four bits
-		 * (it's the result of shifting a 32-bit unsigned
-		 * value Right by 28 bits), so we don't need to
-		 * worry about it becoming invalid as a result.
-		 */
-		if (high_bit) {
-			*first ^= 0x10;
-			ASSERT(!is_invalid_char(*first));
-		}
-
-		ASSERT(libxfs_da_hashname(newname, namelen) == hash);
+		obfuscate_name(hash, namelen, newname);
 
 		/*
 		 * Search the name table to be sure we don't produce

_______________________________________________
xfs mailing list
xfs@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs


[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux