aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs/xfs_attr_leaf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/libxfs/xfs_attr_leaf.c')
-rw-r--r--fs/xfs/libxfs/xfs_attr_leaf.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 6fc5425b1474..2652d00842d6 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -243,7 +243,7 @@ xfs_attr3_leaf_verify(
243 struct xfs_mount *mp = bp->b_target->bt_mount; 243 struct xfs_mount *mp = bp->b_target->bt_mount;
244 struct xfs_attr_leafblock *leaf = bp->b_addr; 244 struct xfs_attr_leafblock *leaf = bp->b_addr;
245 struct xfs_attr_leaf_entry *entries; 245 struct xfs_attr_leaf_entry *entries;
246 uint16_t end; 246 uint32_t end; /* must be 32bit - see below */
247 int i; 247 int i;
248 248
249 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf); 249 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
@@ -293,6 +293,11 @@ xfs_attr3_leaf_verify(
293 /* 293 /*
294 * Quickly check the freemap information. Attribute data has to be 294 * Quickly check the freemap information. Attribute data has to be
295 * aligned to 4-byte boundaries, and likewise for the free space. 295 * aligned to 4-byte boundaries, and likewise for the free space.
296 *
297 * Note that for 64k block size filesystems, the freemap entries cannot
298 * overflow as they are only be16 fields. However, when checking end
299 * pointer of the freemap, we have to be careful to detect overflows and
300 * so use uint32_t for those checks.
296 */ 301 */
297 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { 302 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
298 if (ichdr.freemap[i].base > mp->m_attr_geo->blksize) 303 if (ichdr.freemap[i].base > mp->m_attr_geo->blksize)
@@ -303,7 +308,9 @@ xfs_attr3_leaf_verify(
303 return __this_address; 308 return __this_address;
304 if (ichdr.freemap[i].size & 0x3) 309 if (ichdr.freemap[i].size & 0x3)
305 return __this_address; 310 return __this_address;
306 end = ichdr.freemap[i].base + ichdr.freemap[i].size; 311
312 /* be care of 16 bit overflows here */
313 end = (uint32_t)ichdr.freemap[i].base + ichdr.freemap[i].size;
307 if (end < ichdr.freemap[i].base) 314 if (end < ichdr.freemap[i].base)
308 return __this_address; 315 return __this_address;
309 if (end > mp->m_attr_geo->blksize) 316 if (end > mp->m_attr_geo->blksize)