xfs: catch invalid negative blknos in _xfs_buf_find()
PATCH 1/1 xfs: catch invalid negative blknos in _xfs_buf_find()
Here blkno is a daddr_t, which is a __s64; it's possible to hold a value which is negative, and thus pass the (blkno >= eofs) test. Then we try to do a xfs_perag_get() for a ridiculous agno via xfs_daddr_to_agno(), and bad things happen when that fails, and returns a null pag which is dereferenced shortly thereafter.
Found via a user-supplied fuzzed image...
---
fs/xfs/xfs_buf.c +1 -1
@@ -463,7 +463,7 @@ _xfs_buf_find(* have to check that the buffer falls within the filesystem bounds. */ eofs =XFS_FSB_TO_BB (btp->bt_mount, btp->bt_mount->m_sb.sb_dblocks); -if (blkno >= eofs) { +if (blkno <0 || blkno >= eofs) {/* * XXX (dgc): we should really be returning -EFSCORRUPTED here, * but none of the higher level infrastructure supports
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Eric Sandeen
NAKQuoted 8 lines · Eric Sandeen
Here blkno is a
daddr_t, which is a__s64; it's possible to hold a value which is negative, and thus pass the (blkno >= eofs) test. Then we try to do axfs_perag_get()for a ridiculous agno viaxfs_daddr_to_agno(), and bad things happen when that fails, and returns a null pag which is dereferenced shortly thereafter.Found via a user-supplied fuzzed image...
NAK - this needs a bit more love; if we catch this and fail, the caller may still do something crazy with this data.
V2 coming in a bit.
-Eric
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 10 lines · Eric Sandeen
Here blkno is a
daddr_t, which is a__s64; it's possible to hold a value which is negative, and thus pass the (blkno >= eofs) test. Then we try to do axfs_perag_get()for a ridiculous agno viaxfs_daddr_to_agno(), and bad things happen when that fails, and returns a null pag which is dereferenced shortly thereafter.Found via a user-supplied fuzzed image...
Signed-off-by Eric Sandeen <[email protected]>
Ok, so after further digging, I think this patch is fine on its own, and could use review. How and if and when this function returns errors, and whether errors should get this far, etc, are all subjects for other patches. IF we're range-checking here, we should do both halves of the range checking properly so ... review appreciated.
Thanks,
-Eric
Quoted 16 lines
---
fs/xfs/xfs_buf.c +1
-1@@ -463,7 +463,7 @@ _xfs_buf_find(* have to check that the buffer falls within the filesystem bounds. */ eofs =XFS_FSB_TO_BB (btp->bt_mount, btp->bt_mount->m_sb.sb_dblocks); -if (blkno >= eofs) { +if (blkno <0 || blkno >= eofs) {/* * XXX (dgc): we should really be returning -EFSCORRUPTED here, * but none of the higher level infrastructure supports
Quoted 5 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 11 lines · Eric Sandeen
Here blkno is a
daddr_t, which is a__s64; it's possible to hold a value which is negative, and thus pass the (blkno>= eofs) test. Then we try to do axfs_perag_get()for a ridiculous agno viaxfs_daddr_to_agno(), and bad things happen when that fails, and returns a null pag which is dereferenced shortly thereafter.Found via a user-supplied fuzzed image...
Signed-off-by Eric Sandeen<[email protected]>---
Looks good.
I did a little playing with sending the try lock failure (EAGAIN?) and EFSCORRUPT error status up the stack. It looked straight forward and could save a xfs_buf allocation when we know it is not necessary.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs