[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250924-dir-deleg-v3-1-9f3af8bc5c40@kernel.org>
Date: Wed, 24 Sep 2025 14:05:47 -0400
From: Jeff Layton <jlayton@...nel.org>
To: Alexander Viro <viro@...iv.linux.org.uk>,
Christian Brauner <brauner@...nel.org>, Jan Kara <jack@...e.cz>,
Chuck Lever <chuck.lever@...cle.com>,
Alexander Aring <alex.aring@...il.com>,
Trond Myklebust <trondmy@...nel.org>, Anna Schumaker <anna@...nel.org>,
Steve French <sfrench@...ba.org>,
Ronnie Sahlberg <ronniesahlberg@...il.com>,
Shyam Prasad N <sprasad@...rosoft.com>, Tom Talpey <tom@...pey.com>,
Bharath SM <bharathsm@...rosoft.com>, NeilBrown <neil@...wn.name>,
Olga Kornievskaia <okorniev@...hat.com>, Dai Ngo <Dai.Ngo@...cle.com>,
Jonathan Corbet <corbet@....net>, Amir Goldstein <amir73il@...il.com>,
Miklos Szeredi <miklos@...redi.hu>, Paulo Alcantara <pc@...guebit.org>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
"Rafael J. Wysocki" <rafael@...nel.org>, Danilo Krummrich <dakr@...nel.org>,
David Howells <dhowells@...hat.com>, Tyler Hicks <code@...icks.com>,
Namjae Jeon <linkinjeon@...nel.org>, Steve French <smfrench@...il.com>,
Sergey Senozhatsky <senozhatsky@...omium.org>,
Carlos Maiolino <cem@...nel.org>, Steven Rostedt <rostedt@...dmis.org>,
Masami Hiramatsu <mhiramat@...nel.org>,
Mathieu Desnoyers <mathieu.desnoyers@...icios.com>,
Paulo Alcantara <pc@...guebit.org>
Cc: Rick Macklem <rick.macklem@...il.com>, linux-fsdevel@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-nfs@...r.kernel.org,
linux-cifs@...r.kernel.org, samba-technical@...ts.samba.org,
linux-doc@...r.kernel.org, netfs@...ts.linux.dev, ecryptfs@...r.kernel.org,
linux-unionfs@...r.kernel.org, linux-xfs@...r.kernel.org,
linux-trace-kernel@...r.kernel.org, Jeff Layton <jlayton@...nel.org>
Subject: [PATCH v3 01/38] filelock: push the S_ISREG check down to
->setlease handlers
When nfsd starts requesting directory delegations, setlease handlers may
see requests for leases on directories. Push the !S_ISREG check down
into the non-trivial setlease handlers, so we can selectively enable
them where they're supported.
FUSE is special: It's the only filesystem that supports atomic_open and
allows kernel-internal leases. Ensure that we don't allow directory
leases by default going forward by explicitly disabling them there.
Signed-off-by: Jeff Layton <jlayton@...nel.org>
---
fs/fuse/dir.c | 1 +
fs/locks.c | 5 +++--
fs/nfs/nfs4file.c | 2 ++
fs/smb/client/cifsfs.c | 3 +++
4 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 5c569c3cb53f3d20a9f284124dee657fca5ffc9a..f5288eef5711dca46e78ef6b784ae78737e92201 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -2237,6 +2237,7 @@ static const struct file_operations fuse_dir_operations = {
.fsync = fuse_dir_fsync,
.unlocked_ioctl = fuse_dir_ioctl,
.compat_ioctl = fuse_dir_compat_ioctl,
+ .setlease = simple_nosetlease,
};
static const struct inode_operations fuse_common_inode_operations = {
diff --git a/fs/locks.c b/fs/locks.c
index 559f02aa4172214a14d907b7bc090c1a9235967c..edf34b9859a16c34dd75ce4d1a6a412dd426c875 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1929,6 +1929,9 @@ static int generic_delete_lease(struct file *filp, void *owner)
int generic_setlease(struct file *filp, int arg, struct file_lease **flp,
void **priv)
{
+ if (!S_ISREG(file_inode(filp)->i_mode))
+ return -EINVAL;
+
switch (arg) {
case F_UNLCK:
return generic_delete_lease(filp, *priv);
@@ -2018,8 +2021,6 @@ vfs_setlease(struct file *filp, int arg, struct file_lease **lease, void **priv)
if ((!vfsuid_eq_kuid(vfsuid, current_fsuid())) && !capable(CAP_LEASE))
return -EACCES;
- if (!S_ISREG(inode->i_mode))
- return -EINVAL;
error = security_file_lock(filp, arg);
if (error)
return error;
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index c9a0d1e420c6cb17b209e3f7f48a12dd479dbc24..730e04b8a768debd34ec0c97a0cf0c44f1c18de5 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -431,6 +431,8 @@ void nfs42_ssc_unregister_ops(void)
static int nfs4_setlease(struct file *file, int arg, struct file_lease **lease,
void **priv)
{
+ if (!S_ISREG(file_inode(file)->i_mode))
+ return -EINVAL;
return nfs4_proc_setlease(file, arg, lease, priv);
}
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index e1848276bab41364f894f5f92d7ec08f343aeb1c..8364eed8a246bef43a10bc4078906d8a9aaf26fc 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -1093,6 +1093,9 @@ cifs_setlease(struct file *file, int arg, struct file_lease **lease, void **priv
struct inode *inode = file_inode(file);
struct cifsFileInfo *cfile = file->private_data;
+ if (!S_ISREG(inode->i_mode))
+ return -EINVAL;
+
/* Check if file is oplocked if this is request for new lease */
if (arg == F_UNLCK ||
((arg == F_RDLCK) && CIFS_CACHE_READ(CIFS_I(inode))) ||
--
2.51.0
Powered by blists - more mailing lists