|
@@ -244,6 +244,8 @@ xfs_attr3_leaf_verify(
|
|
|
struct xfs_attr_leafblock *leaf = bp->b_addr;
|
|
|
struct xfs_perag *pag = bp->b_pag;
|
|
|
struct xfs_attr_leaf_entry *entries;
|
|
|
+ uint16_t end;
|
|
|
+ int i;
|
|
|
|
|
|
xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
|
|
|
|
|
@@ -289,6 +291,26 @@ xfs_attr3_leaf_verify(
|
|
|
/* XXX: need to range check rest of attr header values */
|
|
|
/* XXX: hash order check? */
|
|
|
|
|
|
+ /*
|
|
|
+ * Quickly check the freemap information. Attribute data has to be
|
|
|
+ * aligned to 4-byte boundaries, and likewise for the free space.
|
|
|
+ */
|
|
|
+ for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
|
|
|
+ if (ichdr.freemap[i].base > mp->m_attr_geo->blksize)
|
|
|
+ return __this_address;
|
|
|
+ if (ichdr.freemap[i].base & 0x3)
|
|
|
+ return __this_address;
|
|
|
+ if (ichdr.freemap[i].size > mp->m_attr_geo->blksize)
|
|
|
+ return __this_address;
|
|
|
+ if (ichdr.freemap[i].size & 0x3)
|
|
|
+ return __this_address;
|
|
|
+ end = ichdr.freemap[i].base + ichdr.freemap[i].size;
|
|
|
+ if (end < ichdr.freemap[i].base)
|
|
|
+ return __this_address;
|
|
|
+ if (end > mp->m_attr_geo->blksize)
|
|
|
+ return __this_address;
|
|
|
+ }
|
|
|
+
|
|
|
return NULL;
|
|
|
}
|
|
|
|