]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfsprogs: metadump: move obfuscation algorithm into its own function
authorAlex Elder <aelder@sgi.com>
Fri, 18 Feb 2011 21:21:02 +0000 (21:21 +0000)
committerAlex Elder <aelder@sgi.com>
Tue, 8 Mar 2011 18:04:36 +0000 (12:04 -0600)
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@sgi.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
db/metadump.c

index d75b17df93409c607193c97ef985588eea1f5944..5665abdcc3977e2d234d5f08f83906a1810bcb1a 100644 (file)
@@ -475,16 +475,24 @@ 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
-generate_obfuscated_name(
-       xfs_ino_t               ino,
-       int                     namelen,
-       uchar_t                 *name)
+obfuscate_name(
+       xfs_dahash_t    hash,
+       size_t          name_len,
+       uchar_t         *name)
 {
-       xfs_dahash_t            hash;
-       int                     dup = 0;
-       uchar_t                 newname[NAME_MAX];
-       uchar_t                 *newp;
+       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
@@ -493,9 +501,72 @@ generate_obfuscated_name(
         * five bytes in a name required to produce a new name
         * with the same hash.
         */
-       if (namelen < 5)
+       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,
+       int                     namelen,
+       uchar_t                 *name)
+{
+       xfs_dahash_t            hash;
+       int                     dup = 0;
+       uchar_t                 newname[NAME_MAX];
+
        /*
         * We don't obfuscate "lost+found" or any orphan files
         * therein.  When the name table is used for extended
@@ -518,65 +589,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