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

Commit 039c4d7a authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFS: Fix up a race in the NFS implementation of GETLK



 ...and fix a memory corruption bug due to improper use of memcpy() on
 a struct file_lock.

 Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 06735b34
Loading
Loading
Loading
Loading
+18 −9
Original line number Diff line number Diff line
@@ -376,22 +376,31 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t

static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
{
	struct file_lock *cfl;
	struct inode *inode = filp->f_mapping->host;
	int status = 0;

	lock_kernel();
	/* Use local locking if mounted with "-onolock" */
	if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM))
		status = NFS_PROTO(inode)->lock(filp, cmd, fl);
	else {
		struct file_lock *cfl = posix_test_lock(filp, fl);

		fl->fl_type = F_UNLCK;
		if (cfl != NULL)
			memcpy(fl, cfl, sizeof(*fl));
	/* Try local locking first */
	cfl = posix_test_lock(filp, fl);
	if (cfl != NULL) {
		locks_copy_lock(fl, cfl);
		goto out;
	}

	if (nfs_have_delegation(inode, FMODE_READ))
		goto out_noconflict;

	if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)
		goto out_noconflict;

	status = NFS_PROTO(inode)->lock(filp, cmd, fl);
out:
	unlock_kernel();
	return status;
out_noconflict:
	fl->fl_type = F_UNLCK;
	goto out;
}

static int do_vfs_lock(struct file *file, struct file_lock *fl)