xfs: check offsets of variable length structures
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 21 Jun 2016 01:53:28 +0000 (11:53 +1000)
committerDave Chinner <david@fromorbit.com>
Tue, 21 Jun 2016 01:53:28 +0000 (11:53 +1000)
Some of the directory/attr structures contain variable-length objects,
so the enclosing structure doesn't have a meaningful fixed size at
compile time.  We can check the offsets of the members before the
variable-length member, so do those.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fs/xfs/xfs_ondisk.h

index 184c44e..0272301 100644 (file)
        BUILD_BUG_ON_MSG(sizeof(structname) != (size), "XFS: sizeof(" \
                #structname ") is wrong, expected " #size)
 
+#define XFS_CHECK_OFFSET(structname, member, off) \
+       BUILD_BUG_ON_MSG(offsetof(structname, member) != (off), \
+               "XFS: offsetof(" #structname ", " #member ") is wrong, " \
+               "expected " #off)
+
 static inline void __init
 xfs_check_ondisk_structs(void)
 {
@@ -75,15 +80,28 @@ xfs_check_ondisk_structs(void)
        XFS_CHECK_STRUCT_SIZE(xfs_attr_leaf_name_remote_t,      12);
         */
 
+       XFS_CHECK_OFFSET(xfs_attr_leaf_name_local_t, valuelen,  0);
+       XFS_CHECK_OFFSET(xfs_attr_leaf_name_local_t, namelen,   2);
+       XFS_CHECK_OFFSET(xfs_attr_leaf_name_local_t, nameval,   3);
+       XFS_CHECK_OFFSET(xfs_attr_leaf_name_remote_t, valueblk, 0);
+       XFS_CHECK_OFFSET(xfs_attr_leaf_name_remote_t, valuelen, 4);
+       XFS_CHECK_OFFSET(xfs_attr_leaf_name_remote_t, namelen,  8);
+       XFS_CHECK_OFFSET(xfs_attr_leaf_name_remote_t, name,     9);
        XFS_CHECK_STRUCT_SIZE(xfs_attr_leafblock_t,             40);
-       XFS_CHECK_STRUCT_SIZE(xfs_attr_shortform_t,             8);
+       XFS_CHECK_OFFSET(xfs_attr_shortform_t, hdr.totsize,     0);
+       XFS_CHECK_OFFSET(xfs_attr_shortform_t, hdr.count,       2);
+       XFS_CHECK_OFFSET(xfs_attr_shortform_t, list[0].namelen, 4);
+       XFS_CHECK_OFFSET(xfs_attr_shortform_t, list[0].valuelen, 5);
+       XFS_CHECK_OFFSET(xfs_attr_shortform_t, list[0].flags,   6);
+       XFS_CHECK_OFFSET(xfs_attr_shortform_t, list[0].nameval, 7);
        XFS_CHECK_STRUCT_SIZE(xfs_da_blkinfo_t,                 12);
        XFS_CHECK_STRUCT_SIZE(xfs_da_intnode_t,                 16);
        XFS_CHECK_STRUCT_SIZE(xfs_da_node_entry_t,              8);
        XFS_CHECK_STRUCT_SIZE(xfs_da_node_hdr_t,                16);
        XFS_CHECK_STRUCT_SIZE(xfs_dir2_data_free_t,             4);
        XFS_CHECK_STRUCT_SIZE(xfs_dir2_data_hdr_t,              16);
-       XFS_CHECK_STRUCT_SIZE(xfs_dir2_data_unused_t,           6);
+       XFS_CHECK_OFFSET(xfs_dir2_data_unused_t, freetag,       0);
+       XFS_CHECK_OFFSET(xfs_dir2_data_unused_t, length,        2);
        XFS_CHECK_STRUCT_SIZE(xfs_dir2_free_hdr_t,              16);
        XFS_CHECK_STRUCT_SIZE(xfs_dir2_free_t,                  16);
        XFS_CHECK_STRUCT_SIZE(xfs_dir2_ino4_t,                  4);
@@ -94,6 +112,9 @@ xfs_check_ondisk_structs(void)
        XFS_CHECK_STRUCT_SIZE(xfs_dir2_leaf_t,                  16);
        XFS_CHECK_STRUCT_SIZE(xfs_dir2_leaf_tail_t,             4);
        XFS_CHECK_STRUCT_SIZE(xfs_dir2_sf_entry_t,              3);
+       XFS_CHECK_OFFSET(xfs_dir2_sf_entry_t, namelen,          0);
+       XFS_CHECK_OFFSET(xfs_dir2_sf_entry_t, offset,           1);
+       XFS_CHECK_OFFSET(xfs_dir2_sf_entry_t, name,             3);
        XFS_CHECK_STRUCT_SIZE(xfs_dir2_sf_hdr_t,                10);
        XFS_CHECK_STRUCT_SIZE(xfs_dir2_sf_off_t,                2);