From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Eric Biggers <ebiggers3@gmail.com>
Cc: linux-xfs@vger.kernel.org, Eric Biggers <ebiggers@google.com>
Subject: [PATCH v2] xfs: prevent creating negative-sized file via INSERT_RANGE
Date: Mon, 16 Apr 2018 22:39:07 -0700 [thread overview]
Message-ID: <20180417053907.GE5203@magnolia> (raw)
In-Reply-To: <20180417005218.GC5203@magnolia>
How about this instead?
--D
---
From: Eric Biggers <ebiggers@google.com>
During the "insert range" fallocate operation, i_size grows by the
specified 'len' bytes. XFS verifies that i_size + len < s_maxbytes, as
it should. But this comparison is done using the signed 'loff_t', and
'i_size + len' can wrap around to a negative value, causing the check to
incorrectly pass, resulting in an inode with "negative" i_size. This is
possible on 64-bit platforms, where XFS sets s_maxbytes = LLONG_MAX.
ext4 and f2fs don't run into this because they set a smaller s_maxbytes.
Fix it by doing an unsigned comparison instead.
Reproducer:
xfs_io -f file -c "truncate $(((1<<63)-1))" -c "finsert 0 4096"
Fixes: a904b1ca5751 ("xfs: Add support FALLOC_FL_INSERT_RANGE for fallocate")
Cc: <stable@vger.kernel.org> # v4.1+
Signed-off-by: Eric Biggers <ebiggers@google.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
[darrick: rearrange this whole function to use subtraction to avoid
overflow of the signed integer addition]
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
fs/xfs/xfs_file.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 9fd9dd7..a385334 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -779,21 +779,27 @@ xfs_file_fallocate(
goto out_unlock;
} else if (mode & FALLOC_FL_INSERT_RANGE) {
unsigned int blksize_mask = i_blocksize(inode) - 1;
+ loff_t isize;
- new_size = i_size_read(inode) + len;
- if (offset & blksize_mask || len & blksize_mask) {
- error = -EINVAL;
+ isize = i_size_read(inode);
+
+ /*
+ * New inode size must not exceed ->s_maxbytes, accounting for
+ * possible signed overflow.
+ */
+ if (inode->i_sb->s_maxbytes - isize < len) {
+ error = -EFBIG;
goto out_unlock;
}
- /* check the new inode size does not wrap through zero */
- if (new_size > inode->i_sb->s_maxbytes) {
- error = -EFBIG;
+ if (offset & blksize_mask || len & blksize_mask) {
+ error = -EINVAL;
goto out_unlock;
}
+ new_size = isize + len;
/* Offset should be less than i_size */
- if (offset >= i_size_read(inode)) {
+ if (offset >= isize) {
error = -EINVAL;
goto out_unlock;
}
next prev parent reply other threads:[~2018-04-17 5:39 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-04-16 20:46 [PATCH] xfs: prevent creating negative-sized file via INSERT_RANGE Eric Biggers
2018-04-17 0:52 ` Darrick J. Wong
2018-04-17 5:39 ` Darrick J. Wong [this message]
2018-04-17 7:09 ` [PATCH v2] " Christoph Hellwig
2018-04-17 17:55 ` [PATCH v3] " Darrick J. Wong
2018-04-17 18:00 ` Eric Biggers
2018-04-17 18:44 ` Darrick J. Wong
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=20180417053907.GE5203@magnolia \
--to=darrick.wong@oracle.com \
--cc=ebiggers3@gmail.com \
--cc=ebiggers@google.com \
--cc=linux-xfs@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.