Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9fd11e2d authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Greg Kroah-Hartman
Browse files

fuse: lock inode unconditionally in fuse_fallocate()



commit 44361e8cf9ddb23f17bdcc40ca944abf32e83e79 upstream.

file_modified() must be called with inode lock held.  fuse_fallocate()
didn't lock the inode in case of just FALLOC_KEEP_SIZE flags value, which
resulted in a kernel Warning in notify_change().

Lock the inode unconditionally, like all other fallocate implementations
do.

Reported-by: default avatarPengfei Xu <pengfei.xu@intel.com>
Reported-and-tested-by: default avatar <syzbot+462da39f0667b357c4b6@syzkaller.appspotmail.com>
Fixes: 4a6f278d4827 ("fuse: add file_modified() to fallocate")
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3659e33c
Loading
Loading
Loading
Loading
+7 −13
Original line number Diff line number Diff line
@@ -3212,16 +3212,12 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
		.mode = mode
	};
	int err;
	bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) ||
			   (mode & FALLOC_FL_PUNCH_HOLE);

	if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
		return -EOPNOTSUPP;

	if (fc->no_fallocate)
		return -EOPNOTSUPP;

	if (lock_inode) {
	inode_lock(inode);
	if (mode & FALLOC_FL_PUNCH_HOLE) {
		loff_t endbyte = offset + length - 1;
@@ -3230,7 +3226,6 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
		if (err)
			goto out;
	}
	}

	if (!(mode & FALLOC_FL_KEEP_SIZE) &&
	    offset + length > i_size_read(inode)) {
@@ -3276,7 +3271,6 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
	if (!(mode & FALLOC_FL_KEEP_SIZE))
		clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);

	if (lock_inode)
	inode_unlock(inode);

	return err;