diff options
Diffstat (limited to 'fs/xfs/xfs_ialloc.c')
| -rw-r--r-- | fs/xfs/xfs_ialloc.c | 16 | 
1 files changed, 10 insertions, 6 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index abf80ae1e95b..5371d2dc360e 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c @@ -1213,7 +1213,6 @@ xfs_imap_lookup(  	struct xfs_inobt_rec_incore rec;  	struct xfs_btree_cur	*cur;  	struct xfs_buf		*agbp; -	xfs_agino_t		startino;  	int			error;  	int			i; @@ -1227,13 +1226,13 @@ xfs_imap_lookup(  	}  	/* -	 * derive and lookup the exact inode record for the given agino. If the -	 * record cannot be found, then it's an invalid inode number and we -	 * should abort. +	 * Lookup the inode record for the given agino. If the record cannot be +	 * found, then it's an invalid inode number and we should abort. Once +	 * we have a record, we need to ensure it contains the inode number +	 * we are looking up.  	 */  	cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); -	startino = agino & ~(XFS_IALLOC_INODES(mp) - 1); -	error = xfs_inobt_lookup(cur, startino, XFS_LOOKUP_EQ, &i); +	error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i);  	if (!error) {  		if (i)  			error = xfs_inobt_get_rec(cur, &rec, &i); @@ -1246,6 +1245,11 @@ xfs_imap_lookup(  	if (error)  		return error; +	/* check that the returned record contains the required inode */ +	if (rec.ir_startino > agino || +	    rec.ir_startino + XFS_IALLOC_INODES(mp) <= agino) +		return EINVAL; +  	/* for untrusted inodes check it is allocated first */  	if ((flags & XFS_IGET_UNTRUSTED) &&  	    (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino)))  | 
