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@xxxxxxxxxx>
---
Yes, I need to do an xfstest for this. metadumping a filesystem
after fsstressing it works well.
diff --git a/db/metadump.c b/db/metadump.c
index c5ffddb..9f15d9e 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -956,6 +956,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
|