]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs_db: don't obfuscate metadata directories and attributes
authorDarrick J. Wong <djwong@kernel.org>
Wed, 3 Jul 2024 21:21:50 +0000 (14:21 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jul 2024 00:13:17 +0000 (17:13 -0700)
Don't obfuscate the directory and attribute names of metadata inodes.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
db/metadump.c

index 424544f9f032240c7b019fa6827d18eff83d78ef..04f6805099d530a2391f5b635da36a1e3368354b 100644 (file)
@@ -1056,9 +1056,16 @@ add_remap:
                free(orig_name);
 }
 
+static inline bool
+want_obfuscate_dirents(bool is_meta)
+{
+       return metadump.obfuscate && !is_meta;
+}
+
 static void
 process_sf_dir(
-       struct xfs_dinode       *dip)
+       struct xfs_dinode       *dip,
+       bool                    is_meta)
 {
        struct xfs_dir2_sf_hdr  *sfp;
        xfs_dir2_sf_entry_t     *sfep;
@@ -1105,7 +1112,7 @@ process_sf_dir(
                                         (char *)sfp);
                }
 
-               if (metadump.obfuscate)
+               if (want_obfuscate_dirents(is_meta))
                        generate_obfuscated_name(
                                         libxfs_dir2_sf_get_ino(mp, sfp, sfep),
                                         namelen, &sfep->name[0]);
@@ -1201,7 +1208,8 @@ maybe_obfuscate_pptr(
        uint8_t                         *name,
        int                             namelen,
        const void                      *value,
-       int                             valuelen)
+       int                             valuelen,
+       bool                            is_meta)
 {
        unsigned char                   old_name[MAXNAMELEN];
        struct remap_ent                *remap;
@@ -1210,7 +1218,7 @@ maybe_obfuscate_pptr(
        xfs_ino_t                       parent_ino;
        int                             error;
 
-       if (!metadump.obfuscate)
+       if (!metadump.obfuscate || is_meta)
                return;
 
        if (!(attr_flags & XFS_ATTR_PARENT))
@@ -1274,9 +1282,10 @@ want_obfuscate_attr(
        const void      *name,
        unsigned int    namelen,
        const void      *value,
-       unsigned int    valuelen)
+       unsigned int    valuelen,
+       bool            is_meta)
 {
-       if (!metadump.obfuscate)
+       if (!metadump.obfuscate || is_meta)
                return false;
 
        /*
@@ -1291,7 +1300,8 @@ want_obfuscate_attr(
 
 static void
 process_sf_attr(
-       struct xfs_dinode               *dip)
+       struct xfs_dinode               *dip,
+       bool                            is_meta)
 {
        /*
         * with extended attributes, obfuscate the names and fill the actual
@@ -1338,9 +1348,9 @@ process_sf_attr(
 
                if (asfep->flags & XFS_ATTR_PARENT) {
                        maybe_obfuscate_pptr(asfep->flags, name, namelen,
-                                       value, asfep->valuelen);
+                                       value, asfep->valuelen, is_meta);
                } else if (want_obfuscate_attr(asfep->flags, name, namelen,
-                                       value, asfep->valuelen)) {
+                                       value, asfep->valuelen, is_meta)) {
                        generate_obfuscated_name(0, asfep->namelen, name);
                        memset(value, 'v', asfep->valuelen);
                }
@@ -1442,7 +1452,8 @@ static void
 process_dir_data_block(
        char            *block,
        xfs_fileoff_t   offset,
-       int             is_block_format)
+       int             is_block_format,
+       bool            is_meta)
 {
        /*
         * we have to rely on the fileoffset and signature of the block to
@@ -1549,7 +1560,7 @@ process_dir_data_block(
                                dir_offset)
                        return;
 
-               if (metadump.obfuscate)
+               if (want_obfuscate_dirents(is_meta))
                        generate_obfuscated_name(be64_to_cpu(dep->inumber),
                                         dep->namelen, &dep->name[0]);
                dir_offset += length;
@@ -1574,7 +1585,8 @@ process_symlink_block(
        xfs_fsblock_t   s,
        xfs_filblks_t   c,
        typnm_t         btype,
-       xfs_fileoff_t   last)
+       xfs_fileoff_t   last,
+       bool            is_meta)
 {
        struct bbmap    map;
        char            *link;
@@ -1599,7 +1611,7 @@ process_symlink_block(
        if (xfs_has_crc((mp)))
                link += sizeof(struct xfs_dsymlink_hdr);
 
-       if (metadump.obfuscate)
+       if (want_obfuscate_dirents(is_meta))
                obfuscate_path_components(link, XFS_SYMLINK_BUF_SPACE(mp,
                                                        mp->m_sb.sb_blocksize));
        if (metadump.zero_stale_data) {
@@ -1650,7 +1662,8 @@ add_remote_vals(
 static void
 process_attr_block(
        char                            *block,
-       xfs_fileoff_t                   offset)
+       xfs_fileoff_t                   offset,
+       bool                            is_meta)
 {
        struct xfs_attr_leafblock       *leaf;
        struct xfs_attr3_icleaf_hdr     hdr;
@@ -1730,10 +1743,10 @@ process_attr_block(
                        if (entry->flags & XFS_ATTR_PARENT) {
                                maybe_obfuscate_pptr(entry->flags, name,
                                                local->namelen, value,
-                                               valuelen);
+                                               valuelen, is_meta);
                        } else if (want_obfuscate_attr(entry->flags, name,
                                                local->namelen, value,
-                                               valuelen)) {
+                                               valuelen, is_meta)) {
                                generate_obfuscated_name(0, local->namelen,
                                                name);
                                memset(value, 'v', valuelen);
@@ -1759,7 +1772,7 @@ process_attr_block(
                                /* do not obfuscate obviously busted pptr */
                                add_remote_vals(be32_to_cpu(remote->valueblk),
                                                be32_to_cpu(remote->valuelen));
-                       } else if (metadump.obfuscate) {
+                       } else if (want_obfuscate_dirents(is_meta)) {
                                generate_obfuscated_name(0, remote->namelen,
                                                         &remote->name[0]);
                                add_remote_vals(be32_to_cpu(remote->valueblk),
@@ -1792,7 +1805,8 @@ process_single_fsb_objects(
        xfs_fsblock_t   s,
        xfs_filblks_t   c,
        typnm_t         btype,
-       xfs_fileoff_t   last)
+       xfs_fileoff_t   last,
+       bool            is_meta)
 {
        int             rval = 1;
        char            *dp;
@@ -1862,12 +1876,13 @@ process_single_fsb_objects(
                                process_dir_leaf_block(dp);
                        } else {
                                process_dir_data_block(dp, o,
-                                        last == mp->m_dir_geo->fsbcount);
+                                        last == mp->m_dir_geo->fsbcount,
+                                        is_meta);
                        }
                        iocur_top->need_crc = 1;
                        break;
                case TYP_ATTR:
-                       process_attr_block(dp, o);
+                       process_attr_block(dp, o, is_meta);
                        iocur_top->need_crc = 1;
                        break;
                default:
@@ -1900,7 +1915,8 @@ process_multi_fsb_dir(
        xfs_fsblock_t   s,
        xfs_filblks_t   c,
        typnm_t         btype,
-       xfs_fileoff_t   last)
+       xfs_fileoff_t   last,
+       bool            is_meta)
 {
        char            *dp;
        int             rval = 1;
@@ -1944,7 +1960,8 @@ process_multi_fsb_dir(
                                process_dir_leaf_block(dp);
                        } else {
                                process_dir_data_block(dp, o,
-                                        last == mp->m_dir_geo->fsbcount);
+                                        last == mp->m_dir_geo->fsbcount,
+                                        is_meta);
                        }
                        iocur_top->need_crc = 1;
 write:
@@ -1981,13 +1998,14 @@ process_multi_fsb_objects(
        xfs_fsblock_t   s,
        xfs_filblks_t   c,
        typnm_t         btype,
-       xfs_fileoff_t   last)
+       xfs_fileoff_t   last,
+       bool            is_meta)
 {
        switch (btype) {
        case TYP_DIR2:
-               return process_multi_fsb_dir(o, s, c, btype, last);
+               return process_multi_fsb_dir(o, s, c, btype, last, is_meta);
        case TYP_SYMLINK:
-               return process_symlink_block(o, s, c, btype, last);
+               return process_symlink_block(o, s, c, btype, last, is_meta);
        default:
                print_warning("bad type for multi-fsb object %d", btype);
                return 1;
@@ -1999,7 +2017,8 @@ static int
 process_bmbt_reclist(
        xfs_bmbt_rec_t          *rp,
        int                     numrecs,
-       typnm_t                 btype)
+       typnm_t                 btype,
+       bool                    is_meta)
 {
        int                     i;
        xfs_fileoff_t           o, op = NULLFILEOFF;
@@ -2079,10 +2098,10 @@ process_bmbt_reclist(
                /* multi-extent blocks require special handling */
                if (is_multi_fsb)
                        rval = process_multi_fsb_objects(o, s, c, btype,
-                                       last);
+                                       last, is_meta);
                else
                        rval = process_single_fsb_objects(o, s, c, btype,
-                                       last);
+                                       last, is_meta);
                if (!rval)
                        break;
        }
@@ -2090,6 +2109,11 @@ process_bmbt_reclist(
        return rval;
 }
 
+struct scan_bmap {
+       enum typnm      typ;
+       bool            is_meta;
+};
+
 static int
 scanfunc_bmap(
        struct xfs_btree_block  *block,
@@ -2099,6 +2123,7 @@ scanfunc_bmap(
        typnm_t                 btype,
        void                    *arg)   /* ptr to itype */
 {
+       struct scan_bmap        *sbm = arg;
        int                     i;
        xfs_bmbt_ptr_t          *pp;
        int                     nrecs;
@@ -2114,7 +2139,7 @@ scanfunc_bmap(
                        return 1;
                }
                return process_bmbt_reclist(XFS_BMBT_REC_ADDR(mp, block, 1),
-                                           nrecs, *(typnm_t*)arg);
+                                           nrecs, sbm->typ, sbm->is_meta);
        }
 
        if (nrecs > mp->m_bmap_dmxr[1]) {
@@ -2146,6 +2171,15 @@ scanfunc_bmap(
        return 1;
 }
 
+static inline bool
+is_metadata_ino(
+       struct xfs_dinode       *dip)
+{
+       return xfs_has_metadir(mp) &&
+                       dip->di_version >= 3 &&
+                       (dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADATA));
+}
+
 static int
 process_btinode(
        struct xfs_dinode       *dip,
@@ -2159,6 +2193,7 @@ process_btinode(
        int                     maxrecs;
        int                     whichfork;
        typnm_t                 btype;
+       bool                    is_meta = is_metadata_ino(dip);
 
        whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK;
        btype = (itype == TYP_ATTR) ? TYP_BMAPBTA : TYP_BMAPBTD;
@@ -2177,7 +2212,7 @@ process_btinode(
 
        if (level == 0) {
                return process_bmbt_reclist(XFS_BMDR_REC_ADDR(dib, 1),
-                                           nrecs, itype);
+                                           nrecs, itype, is_meta);
        }
 
        maxrecs = libxfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip, mp, whichfork), 0);
@@ -2204,6 +2239,10 @@ process_btinode(
        }
 
        for (i = 0; i < nrecs; i++) {
+               struct scan_bmap        sbm = {
+                       .typ = itype,
+                       .is_meta = is_meta,
+               };
                xfs_agnumber_t  ag;
                xfs_agblock_t   bno;
 
@@ -2220,7 +2259,7 @@ process_btinode(
                        continue;
                }
 
-               if (!scan_btree(ag, bno, level, btype, &itype, scanfunc_bmap))
+               if (!scan_btree(ag, bno, level, btype, &sbm, scanfunc_bmap))
                        return 0;
        }
        return 1;
@@ -2234,6 +2273,7 @@ process_exinode(
        int                     whichfork;
        int                     used;
        xfs_extnum_t            nex, max_nex;
+       bool                    is_meta = is_metadata_ino(dip);
 
        whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK;
 
@@ -2258,7 +2298,7 @@ process_exinode(
 
 
        return process_bmbt_reclist((xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip,
-                                       whichfork), nex, itype);
+                                       whichfork), nex, itype, is_meta);
 }
 
 static int
@@ -2266,6 +2306,8 @@ process_inode_data(
        struct xfs_dinode       *dip,
        typnm_t                 itype)
 {
+       bool                    is_meta = is_metadata_ino(dip);
+
        switch (dip->di_format) {
                case XFS_DINODE_FMT_LOCAL:
                        if (!(metadump.obfuscate || metadump.zero_stale_data))
@@ -2286,7 +2328,7 @@ process_inode_data(
 
                        switch (itype) {
                                case TYP_DIR2:
-                                       process_sf_dir(dip);
+                                       process_sf_dir(dip, is_meta);
                                        break;
 
                                case TYP_SYMLINK:
@@ -2404,13 +2446,15 @@ process_inode(
 
        /* copy extended attributes if they exist and forkoff is valid */
        if (XFS_DFORK_DSIZE(dip, mp) < XFS_LITINO(mp)) {
+               bool    is_meta = is_metadata_ino(dip);
+
                attr_data.remote_val_count = 0;
                switch (dip->di_aformat) {
                        case XFS_DINODE_FMT_LOCAL:
                                need_new_crc = true;
                                if (metadump.obfuscate ||
                                    metadump.zero_stale_data)
-                                       process_sf_attr(dip);
+                                       process_sf_attr(dip, is_meta);
                                break;
 
                        case XFS_DINODE_FMT_EXTENTS: