mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-15 15:23:23 -04:00
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:
@@ -565,6 +565,19 @@ xfs_getfsmap_rtdev_rtbitmap(
|
||||
}
|
||||
#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;
|
||||
|
||||
Reference in New Issue
Block a user