mirror of
https://github.com/torvalds/linux.git
synced 2024-12-02 09:01:34 +00:00
xfs: fix fsmap cursor handling [v2]
This patchset addresses an integer overflow bug that Dave Chinner found in how fsmap handles figuring out where in the record set we left off when userspace calls back after the first call filled up all the designated record space. v2: add RVB tags This has been lightly tested with fstests. Enjoy! Signed-off-by: Darrick J. Wong <djwong@kernel.org> -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQ2qTKExjcn+O1o2YRKO3ySh0YRpgUCZQChMwAKCRBKO3ySh0YR prqBAP9Zp2WxwQuNQLqCfXBRLZiJRiW8JFcTNJOjdqIicsOPYgEAxs1GHJU4ozrO bKyolvNJIjSow7LWYP1GmfCRa9FqwQ4= =3uSx -----END PGP SIGNATURE----- Merge tag 'fix-fsmap-6.6_2023-09-12' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into xfs-6.6-fixesA xfs: fix fsmap cursor handling This patchset addresses an integer overflow bug that Dave Chinner found in how fsmap handles figuring out where in the record set we left off when userspace calls back after the first call filled up all the designated record space. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Chandan Babu R <chandanbabu@kernel.org> * tag 'fix-fsmap-6.6_2023-09-12' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux: xfs: fix an agbno overflow in __xfs_getfsmap_datadev
This commit is contained in:
commit
da6f8410e7
@ -565,6 +565,19 @@ err:
|
||||
}
|
||||
#endif /* CONFIG_XFS_RT */
|
||||
|
||||
static inline bool
|
||||
rmap_not_shareable(struct xfs_mount *mp, const struct xfs_rmap_irec *r)
|
||||
{
|
||||
if (!xfs_has_reflink(mp))
|
||||
return true;
|
||||
if (XFS_RMAP_NON_INODE_OWNER(r->rm_owner))
|
||||
return true;
|
||||
if (r->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK |
|
||||
XFS_RMAP_UNWRITTEN))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Execute a getfsmap query against the regular data device. */
|
||||
STATIC int
|
||||
__xfs_getfsmap_datadev(
|
||||
@ -598,7 +611,6 @@ __xfs_getfsmap_datadev(
|
||||
* low to the fsmap low key and max out the high key to the end
|
||||
* of the AG.
|
||||
*/
|
||||
info->low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb);
|
||||
info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset);
|
||||
error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]);
|
||||
if (error)
|
||||
@ -608,12 +620,9 @@ __xfs_getfsmap_datadev(
|
||||
|
||||
/* Adjust the low key if we are continuing from where we left off. */
|
||||
if (info->low.rm_blockcount == 0) {
|
||||
/* empty */
|
||||
} else if (XFS_RMAP_NON_INODE_OWNER(info->low.rm_owner) ||
|
||||
(info->low.rm_flags & (XFS_RMAP_ATTR_FORK |
|
||||
XFS_RMAP_BMBT_BLOCK |
|
||||
XFS_RMAP_UNWRITTEN))) {
|
||||
info->low.rm_startblock += info->low.rm_blockcount;
|
||||
/* No previous record from which to continue */
|
||||
} else if (rmap_not_shareable(mp, &info->low)) {
|
||||
/* Last record seen was an unshareable extent */
|
||||
info->low.rm_owner = 0;
|
||||
info->low.rm_offset = 0;
|
||||
|
||||
@ -621,8 +630,10 @@ __xfs_getfsmap_datadev(
|
||||
if (XFS_FSB_TO_DADDR(mp, start_fsb) >= eofs)
|
||||
return 0;
|
||||
} else {
|
||||
/* Last record seen was a shareable file data extent */
|
||||
info->low.rm_offset += info->low.rm_blockcount;
|
||||
}
|
||||
info->low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb);
|
||||
|
||||
info->high.rm_startblock = -1U;
|
||||
info->high.rm_owner = ULLONG_MAX;
|
||||
|
Loading…
Reference in New Issue
Block a user