]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
metadump: obfuscate symlinks by path component
authorEric Sandeen <sandeen@redhat.com>
Tue, 10 Apr 2012 04:34:12 +0000 (23:34 -0500)
committerBen Myers <bpm@sgi.com>
Thu, 17 Jan 2013 22:23:03 +0000 (16:23 -0600)
xfs_metadump currently obfuscates entire symlinks without regard
to path components; this can lead to a corrupt image when restoring
a metadump containing extremely long symlinks:

Phase 3 - for each AG...
        - scan and clear agi unlinked lists...
        - process known inodes and perform inode discovery...
        - agno = 0
component of symlink in inode 145 too long
problem with symbolic link in inode 145
cleared inode 145
... <more trail of woe>

Fix this by consolidating symlink obfuscation into a new
function which obfuscates one path component at a time.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Alex Elder <elder@kernel.org>
Signed-off-by: Ben Myers <bpm@sgi.com>
db/metadump.c

index c5ffddbcd7a5e2a0358e777e1a87479645f700a7..9f15d9e576f9fc30f17794be85cbea93db94d4d0 100644 (file)
@@ -955,6 +955,40 @@ obfuscate_sf_dir(
        }
 }
 
+static void
+obfuscate_path_components(
+       char                    *buf,
+       __uint64_t              len)
+{
+       uchar_t                 *comp;
+       xfs_dahash_t            hash;
+
+       comp = (uchar_t *)buf;
+       while (comp < (uchar_t *)buf + len) {
+               char    *slash;
+               int     namelen;
+
+               /* find slash at end of this component */
+               slash = strchr((char *)comp, '/');
+               if (!slash) {
+                       /* last (or single) component */
+                       namelen = strlen((char *)comp);
+                       hash = libxfs_da_hashname(comp, namelen);
+                       obfuscate_name(hash, namelen, comp);
+                       break;
+               }
+               namelen = slash - (char *)comp;
+               /* handle leading or consecutive slashes */
+               if (!namelen) {
+                       comp++;
+                       continue;
+               }
+               hash = libxfs_da_hashname(comp, namelen);
+               obfuscate_name(hash, namelen, comp);
+               comp += namelen + 1;
+       }
+}
+
 static void
 obfuscate_sf_symlink(
        xfs_dinode_t            *dip)
@@ -971,8 +1005,7 @@ obfuscate_sf_symlink(
        }
 
        buf = (char *)XFS_DFORK_DPTR(dip);
-       while (len > 0)
-               buf[--len] = random() % 127 + 1;
+       obfuscate_path_components(buf, len);
 }
 
 static void
@@ -1176,11 +1209,8 @@ obfuscate_symlink_blocks(
        char                    *block,
        xfs_dfilblks_t          count)
 {
-       int                     i;
-
        count <<= mp->m_sb.sb_blocklog;
-       for (i = 0; i < count; i++)
-               block[i] = random() % 127 + 1;
+       obfuscate_path_components(block, count);
 }
 
 #define MAX_REMOTE_VALS                4095