Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xfs: distinguish between bnobt and cntbt magic values

The allocation btree verifiers share code that is unable to detect
cross-tree magic value corruptions such as a bnobt block with a
cntbt magic value. Populate the b_ops->magic field of the associated
verifier structures such that the structure verifier can check the
magic value against the expected value based on tree type.

The btree level check requires knowledge of the tree type to
determine the appropriate maximum value. This was previously part of
the hardcoded magic value checks. With that code removed, peek at
the first magic value in the verifier to determine the expected tree
type of the current block.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

authored by

Brian Foster and committed by
Darrick J. Wong
b8f89801 27df4f50

+25 -35
+25 -35
fs/xfs/libxfs/xfs_alloc_btree.c
··· 297 297 struct xfs_perag *pag = bp->b_pag; 298 298 xfs_failaddr_t fa; 299 299 unsigned int level; 300 + xfs_btnum_t btnum = XFS_BTNUM_BNOi; 301 + 302 + if (!xfs_verify_magic(bp, block->bb_magic)) 303 + return __this_address; 304 + 305 + if (xfs_sb_version_hascrc(&mp->m_sb)) { 306 + fa = xfs_btree_sblock_v5hdr_verify(bp); 307 + if (fa) 308 + return fa; 309 + } 300 310 301 311 /* 302 - * magic number and level verification 312 + * The perag may not be attached during grow operations or fully 313 + * initialized from the AGF during log recovery. Therefore we can only 314 + * check against maximum tree depth from those contexts. 303 315 * 304 - * During growfs operations, we can't verify the exact level or owner as 305 - * the perag is not fully initialised and hence not attached to the 306 - * buffer. In this case, check against the maximum tree depth. 307 - * 308 - * Similarly, during log recovery we will have a perag structure 309 - * attached, but the agf information will not yet have been initialised 310 - * from the on disk AGF. Again, we can only check against maximum limits 311 - * in this case. 316 + * Otherwise check against the per-tree limit. Peek at one of the 317 + * verifier magic values to determine the type of tree we're verifying 318 + * against. 312 319 */ 313 320 level = be16_to_cpu(block->bb_level); 314 - switch (block->bb_magic) { 315 - case cpu_to_be32(XFS_ABTB_CRC_MAGIC): 316 - fa = xfs_btree_sblock_v5hdr_verify(bp); 317 - if (fa) 318 - return fa; 319 - /* fall through */ 320 - case cpu_to_be32(XFS_ABTB_MAGIC): 321 - if (pag && pag->pagf_init) { 322 - if (level >= pag->pagf_levels[XFS_BTNUM_BNOi]) 323 - return __this_address; 324 - } else if (level >= mp->m_ag_maxlevels) 321 + if (bp->b_ops->magic[0] == cpu_to_be32(XFS_ABTC_MAGIC)) 322 + btnum = XFS_BTNUM_CNTi; 323 + if (pag && pag->pagf_init) { 324 + if (level >= pag->pagf_levels[btnum]) 325 325 return __this_address; 326 - break; 327 - case cpu_to_be32(XFS_ABTC_CRC_MAGIC): 328 - fa = xfs_btree_sblock_v5hdr_verify(bp); 329 - if (fa) 330 - return fa; 331 - /* fall through */ 332 - case cpu_to_be32(XFS_ABTC_MAGIC): 333 - if (pag && pag->pagf_init) { 334 - if (level >= pag->pagf_levels[XFS_BTNUM_CNTi]) 335 - return __this_address; 336 - } else if (level >= mp->m_ag_maxlevels) 337 - return __this_address; 338 - break; 339 - default: 326 + } else if (level >= mp->m_ag_maxlevels) 340 327 return __this_address; 341 - } 342 328 343 329 return xfs_btree_sblock_verify(bp, mp->m_alloc_mxr[level != 0]); 344 330 } ··· 365 379 366 380 const struct xfs_buf_ops xfs_bnobt_buf_ops = { 367 381 .name = "xfs_bnobt", 382 + .magic = { cpu_to_be32(XFS_ABTB_MAGIC), 383 + cpu_to_be32(XFS_ABTB_CRC_MAGIC) }, 368 384 .verify_read = xfs_allocbt_read_verify, 369 385 .verify_write = xfs_allocbt_write_verify, 370 386 .verify_struct = xfs_allocbt_verify, ··· 374 386 375 387 const struct xfs_buf_ops xfs_cntbt_buf_ops = { 376 388 .name = "xfs_cntbt", 389 + .magic = { cpu_to_be32(XFS_ABTC_MAGIC), 390 + cpu_to_be32(XFS_ABTC_CRC_MAGIC) }, 377 391 .verify_read = xfs_allocbt_read_verify, 378 392 .verify_write = xfs_allocbt_write_verify, 379 393 .verify_struct = xfs_allocbt_verify,