From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
linux-xfs@vger.kernel.org,
"Darrick J. Wong" <darrick.wong@oracle.com>,
Eric Sandeen <sandeen@redhat.com>
Subject: [PATCH 4.9 51/51] xfs: fix bmv_count confusion w/ shared extents
Date: Thu, 2 Feb 2017 19:38:10 +0100 [thread overview]
Message-ID: <20170202183347.839401883@linuxfoundation.org> (raw)
In-Reply-To: <20170202183345.067336143@linuxfoundation.org>
4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Darrick J. Wong" <darrick.wong@oracle.com>
commit c364b6d0b6cda1cd5d9ab689489adda3e82529aa upstream.
In a bmapx call, bmv_count is the total size of the array, including the
zeroth element that userspace uses to supply the search key. The output
array starts at offset 1 so that we can set up the user for the next
invocation. Since we now can split an extent into multiple bmap records
due to shared/unshared status, we have to be careful that we don't
overflow the output array.
In the original patch f86f403794b ("xfs: teach get_bmapx about shared
extents and the CoW fork") I used cur_ext (the output index) to check
for overflows, albeit with an off-by-one error. Since nexleft no longer
describes the number of unfilled slots in the output, we can rip all
that out and use cur_ext for the overflow check directly.
Failure to do this causes heap corruption in bmapx callers such as
xfs_io and xfs_scrub. xfs/328 can reproduce this problem.
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_bmap_util.c | 28 ++++++++++++++++++----------
1 file changed, 18 insertions(+), 10 deletions(-)
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -528,7 +528,6 @@ xfs_getbmap(
xfs_bmbt_irec_t *map; /* buffer for user's data */
xfs_mount_t *mp; /* file system mount point */
int nex; /* # of user extents can do */
- int nexleft; /* # of user extents left */
int subnex; /* # of bmapi's can do */
int nmap; /* number of map entries */
struct getbmapx *out; /* output structure */
@@ -686,10 +685,8 @@ xfs_getbmap(
goto out_free_map;
}
- nexleft = nex;
-
do {
- nmap = (nexleft > subnex) ? subnex : nexleft;
+ nmap = (nex> subnex) ? subnex : nex;
error = xfs_bmapi_read(ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
XFS_BB_TO_FSB(mp, bmv->bmv_length),
map, &nmap, bmapi_flags);
@@ -697,8 +694,8 @@ xfs_getbmap(
goto out_free_map;
ASSERT(nmap <= subnex);
- for (i = 0; i < nmap && nexleft && bmv->bmv_length &&
- cur_ext < bmv->bmv_count; i++) {
+ for (i = 0; i < nmap && bmv->bmv_length &&
+ cur_ext < bmv->bmv_count - 1; i++) {
out[cur_ext].bmv_oflags = 0;
if (map[i].br_state == XFS_EXT_UNWRITTEN)
out[cur_ext].bmv_oflags |= BMV_OF_PREALLOC;
@@ -760,16 +757,27 @@ xfs_getbmap(
continue;
}
+ /*
+ * In order to report shared extents accurately,
+ * we report each distinct shared/unshared part
+ * of a single bmbt record using multiple bmap
+ * extents. To make that happen, we iterate the
+ * same map array item multiple times, each
+ * time trimming out the subextent that we just
+ * reported.
+ *
+ * Because of this, we must check the out array
+ * index (cur_ext) directly against bmv_count-1
+ * to avoid overflows.
+ */
if (inject_map.br_startblock != NULLFSBLOCK) {
map[i] = inject_map;
i--;
- } else
- nexleft--;
+ }
bmv->bmv_entries++;
cur_ext++;
}
- } while (nmap && nexleft && bmv->bmv_length &&
- cur_ext < bmv->bmv_count);
+ } while (nmap && bmv->bmv_length && cur_ext < bmv->bmv_count - 1);
out_free_map:
kmem_free(map);
prev parent reply other threads:[~2017-02-02 18:40 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20170202183345.067336143@linuxfoundation.org>
2017-02-02 18:37 ` [PATCH 4.9 33/51] xfs: bump up reserved blocks in xfs_alloc_set_aside Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 34/51] xfs: fix bogus minleft manipulations Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 35/51] xfs: adjust allocation length in xfs_alloc_space_available Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 36/51] xfs: dont rely on ->total " Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 37/51] xfs: dont print warnings when xfs_log_force fails Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 46/51] xfs: fix COW writeback race Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 47/51] xfs: verify dirblocklog correctly Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 49/51] xfs: extsize hints are not unlikely in xfs_bmap_btalloc Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 50/51] xfs: clear _XBF_PAGES from buffers when readahead page Greg Kroah-Hartman
2017-02-02 18:38 ` Greg Kroah-Hartman [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170202183347.839401883@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=darrick.wong@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
--cc=sandeen@redhat.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).