Commit 48a2f0b2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'xfs-for-linus-v3.13-rc4' of git://oss.sgi.com/xfs/xfs

Pull xfs bugfixes from Ben Myers:

 - fix for buffer overrun in agfl with growfs on v4 superblock

 - return EINVAL if requested discard length is less than a block

 - fix possible memory corruption in xfs_attrlist_by_handle()

* tag 'xfs-for-linus-v3.13-rc4' of git://oss.sgi.com/xfs/xfs:
  xfs: growfs overruns AGFL buffer on V4 filesystems
  xfs: don't perform discard if the given range length is less than block size
  xfs: underflow bug in xfs_attrlist_by_handle()
parents 5cdec2d8 f94c4457
...@@ -157,7 +157,7 @@ xfs_ioc_trim( ...@@ -157,7 +157,7 @@ xfs_ioc_trim(
struct xfs_mount *mp, struct xfs_mount *mp,
struct fstrim_range __user *urange) struct fstrim_range __user *urange)
{ {
struct request_queue *q = mp->m_ddev_targp->bt_bdev->bd_disk->queue; struct request_queue *q = bdev_get_queue(mp->m_ddev_targp->bt_bdev);
unsigned int granularity = q->limits.discard_granularity; unsigned int granularity = q->limits.discard_granularity;
struct fstrim_range range; struct fstrim_range range;
xfs_daddr_t start, end, minlen; xfs_daddr_t start, end, minlen;
...@@ -180,7 +180,8 @@ xfs_ioc_trim( ...@@ -180,7 +180,8 @@ xfs_ioc_trim(
* matter as trimming blocks is an advisory interface. * matter as trimming blocks is an advisory interface.
*/ */
if (range.start >= XFS_FSB_TO_B(mp, mp->m_sb.sb_dblocks) || if (range.start >= XFS_FSB_TO_B(mp, mp->m_sb.sb_dblocks) ||
range.minlen > XFS_FSB_TO_B(mp, XFS_ALLOC_AG_MAX_USABLE(mp))) range.minlen > XFS_FSB_TO_B(mp, XFS_ALLOC_AG_MAX_USABLE(mp)) ||
range.len < mp->m_sb.sb_blocksize)
return -XFS_ERROR(EINVAL); return -XFS_ERROR(EINVAL);
start = BTOBB(range.start); start = BTOBB(range.start);
......
...@@ -220,6 +220,8 @@ xfs_growfs_data_private( ...@@ -220,6 +220,8 @@ xfs_growfs_data_private(
*/ */
nfree = 0; nfree = 0;
for (agno = nagcount - 1; agno >= oagcount; agno--, new -= agsize) { for (agno = nagcount - 1; agno >= oagcount; agno--, new -= agsize) {
__be32 *agfl_bno;
/* /*
* AG freespace header block * AG freespace header block
*/ */
...@@ -279,8 +281,10 @@ xfs_growfs_data_private( ...@@ -279,8 +281,10 @@ xfs_growfs_data_private(
agfl->agfl_seqno = cpu_to_be32(agno); agfl->agfl_seqno = cpu_to_be32(agno);
uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_uuid); uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_uuid);
} }
agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, bp);
for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++) for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++)
agfl->agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK); agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
error = xfs_bwrite(bp); error = xfs_bwrite(bp);
xfs_buf_relse(bp); xfs_buf_relse(bp);
......
...@@ -442,7 +442,8 @@ xfs_attrlist_by_handle( ...@@ -442,7 +442,8 @@ xfs_attrlist_by_handle(
return -XFS_ERROR(EPERM); return -XFS_ERROR(EPERM);
if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t))) if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
return -XFS_ERROR(EFAULT); return -XFS_ERROR(EFAULT);
if (al_hreq.buflen > XATTR_LIST_MAX) if (al_hreq.buflen < sizeof(struct attrlist) ||
al_hreq.buflen > XATTR_LIST_MAX)
return -XFS_ERROR(EINVAL); return -XFS_ERROR(EINVAL);
/* /*
......
...@@ -356,7 +356,8 @@ xfs_compat_attrlist_by_handle( ...@@ -356,7 +356,8 @@ xfs_compat_attrlist_by_handle(
if (copy_from_user(&al_hreq, arg, if (copy_from_user(&al_hreq, arg,
sizeof(compat_xfs_fsop_attrlist_handlereq_t))) sizeof(compat_xfs_fsop_attrlist_handlereq_t)))
return -XFS_ERROR(EFAULT); return -XFS_ERROR(EFAULT);
if (al_hreq.buflen > XATTR_LIST_MAX) if (al_hreq.buflen < sizeof(struct attrlist) ||
al_hreq.buflen > XATTR_LIST_MAX)
return -XFS_ERROR(EINVAL); return -XFS_ERROR(EINVAL);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment