@@ -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;
}