lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230608084609.14245-2-zhangjiachen.jaycee@bytedance.com>
Date:   Thu,  8 Jun 2023 16:46:08 +0800
From:   Jiachen Zhang <zhangjiachen.jaycee@...edance.com>
To:     Miklos Szeredi <miklos@...redi.hu>, linux-fsdevel@...r.kernel.org,
        linux-kernel@...r.kernel.org
Cc:     Andrew Morton <akpm@...l.org>, me@...x.top,
        Jiachen Zhang <zhangjiachen.jaycee@...edance.com>
Subject: [PATCH 1/2] fuse: support unlock remote OFD locks on file release

Like flock(2), the fcntl(2) OFD locks also use struct file addresses as
the lock owner ID, and also should be unlocked on file release.

The commit 37fb3a30b462 ("fuse: fix flock") fixed the flock unlocking
issue on file release. This commit aims to fix the OFD lock by reusing
the release_flag 'FUSE_RELEASE_FLOCK_UNLOCK'. The FUSE daemons should
unlock both OFD locks and flocks in the FUSE_RELEASE handler.

To make it more clear, rename 'ff->flock' to 'ff->unlock_on_release', as
it would be used for both flock and OFD lock. It will be set true if the
value of fl->fl_owner equals to the struct file address.

Fixes: 37fb3a30b462 ("fuse: fix flock")
Signed-off-by: Jiachen Zhang <zhangjiachen.jaycee@...edance.com>
---
 fs/fuse/file.c   | 17 ++++++++++++++---
 fs/fuse/fuse_i.h |  2 +-
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index de37a3a06a71..7fe9d405969e 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -312,7 +312,7 @@ void fuse_file_release(struct inode *inode, struct fuse_file *ff,
 
 	fuse_prepare_release(fi, ff, open_flags, opcode);
 
-	if (ff->flock) {
+	if (ff->unlock_on_release) {
 		ra->inarg.release_flags |= FUSE_RELEASE_FLOCK_UNLOCK;
 		ra->inarg.lock_owner = fuse_lock_owner_id(ff->fm->fc, id);
 	}
@@ -2650,8 +2650,19 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)
 	} else {
 		if (fc->no_lock)
 			err = posix_lock_file(file, fl, NULL);
-		else
+		else {
+			/*
+			 * Like flock, the OFD lock also uses the struct
+			 * file address as the fl_owner, and should be
+			 * unlocked on file release.
+			 */
+			if (file == fl->fl_owner) {
+				struct fuse_file *ff = file->private_data;
+
+				ff->unlock_on_release = true;
+			}
 			err = fuse_setlk(file, fl, 0);
+		}
 	}
 	return err;
 }
@@ -2668,7 +2679,7 @@ static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl)
 		struct fuse_file *ff = file->private_data;
 
 		/* emulate flock with POSIX locks */
-		ff->flock = true;
+		ff->unlock_on_release = true;
 		err = fuse_setlk(file, fl, 1);
 	}
 
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 9b7fc7d3c7f1..574f67bd5684 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -225,7 +225,7 @@ struct fuse_file {
 	wait_queue_head_t poll_wait;
 
 	/** Has flock been performed on this file? */
-	bool flock:1;
+	bool unlock_on_release:1;
 };
 
 /** One input argument of a request */
-- 
2.20.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ