xfs: catch bad block numbers freeing extents.
A fuzzed filesystem crashed a kernel when freeing an extent with a block number beyond the end of the filesystem. Convert all the debug asserts in xfs_free_extent() to active checks so that we catch bad extents and return that the filesytsem is corrupted rather than crashing. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Alex Elder <aelder@sgi.com>
This commit is contained in:
parent
fd074841cf
commit
be65b18a10
@ -2395,17 +2395,33 @@ xfs_free_extent(
|
|||||||
memset(&args, 0, sizeof(xfs_alloc_arg_t));
|
memset(&args, 0, sizeof(xfs_alloc_arg_t));
|
||||||
args.tp = tp;
|
args.tp = tp;
|
||||||
args.mp = tp->t_mountp;
|
args.mp = tp->t_mountp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* validate that the block number is legal - the enables us to detect
|
||||||
|
* and handle a silent filesystem corruption rather than crashing.
|
||||||
|
*/
|
||||||
args.agno = XFS_FSB_TO_AGNO(args.mp, bno);
|
args.agno = XFS_FSB_TO_AGNO(args.mp, bno);
|
||||||
ASSERT(args.agno < args.mp->m_sb.sb_agcount);
|
if (args.agno >= args.mp->m_sb.sb_agcount)
|
||||||
|
return EFSCORRUPTED;
|
||||||
|
|
||||||
args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno);
|
args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno);
|
||||||
|
if (args.agbno >= args.mp->m_sb.sb_agblocks)
|
||||||
|
return EFSCORRUPTED;
|
||||||
|
|
||||||
args.pag = xfs_perag_get(args.mp, args.agno);
|
args.pag = xfs_perag_get(args.mp, args.agno);
|
||||||
if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING)))
|
ASSERT(args.pag);
|
||||||
|
|
||||||
|
error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING);
|
||||||
|
if (error)
|
||||||
goto error0;
|
goto error0;
|
||||||
#ifdef DEBUG
|
|
||||||
ASSERT(args.agbp != NULL);
|
/* validate the extent size is legal now we have the agf locked */
|
||||||
ASSERT((args.agbno + len) <=
|
if (args.agbno + len >
|
||||||
be32_to_cpu(XFS_BUF_TO_AGF(args.agbp)->agf_length));
|
be32_to_cpu(XFS_BUF_TO_AGF(args.agbp)->agf_length)) {
|
||||||
#endif
|
error = EFSCORRUPTED;
|
||||||
|
goto error0;
|
||||||
|
}
|
||||||
|
|
||||||
error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0);
|
error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0);
|
||||||
error0:
|
error0:
|
||||||
xfs_perag_put(args.pag);
|
xfs_perag_put(args.pag);
|
||||||
|
Loading…
Reference in New Issue
Block a user