|
@@ -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)))
|