From 5859cc01fee06a2cd7458905a9593082fbab06e1 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 26 May 2026 15:27:59 +1000 Subject: [PATCH] nfsd: ensure nfsd_file_do_acquire() does not use a non-opened file ->atomic_open is permitted to return success without actually opening the file. It indicates this by calling finish_no_open(). This means dentry_create() can return a file which hasn't been opened. This is extremely unlikely as ->atomic_open handlers typically use finish_no_open() only for already existing files, and dentry_create() isn't called in that case, and the parent being locked should prevent races. However out of an abundance of caution it seems wise to teach nfsd to only use the file returned by dentry_create() if FMODE_OPENED is set, indicating that it has in fact been opened. Fixes: 64a989dbd144 ("VFS/knfsd: Teach dentry_create() to use atomic_open()") Cc: stable@vger.kernel.org Signed-off-by: NeilBrown Link: https://patch.msgid.link/20260526053004.4014491-3-neilb@ownmail.net Signed-off-by: Chuck Lever Reviewed-by: Jeff Layton Reviewed-by: Benjamin Coddington --- fs/nfsd/filecache.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 24511c3208db..3b5f18fb713f 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -1227,7 +1227,7 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct net *net, nf->nf_mark = nfsd_file_mark_find_or_create(inode); if (type != S_IFREG || nf->nf_mark) { - if (file) { + if (file && (file->f_mode & FMODE_OPENED)) { get_file(file); nf->nf_file = file; status = nfs_ok; @@ -1374,12 +1374,12 @@ nfsd_file_acquire_local(struct net *net, struct svc_cred *cred, * @rqstp: the RPC transaction being executed * @fhp: the NFS filehandle of the file just created * @may_flags: NFSD_MAY_ settings for the file - * @file: cached, already-open file (may be NULL) + * @file: cached, already-open file (may be NULL or not yet opened) * @pnf: OUT: new or found "struct nfsd_file" object * * Acquire a nfsd_file object that is not GC'ed. If one doesn't already exist, - * and @file is non-NULL, use it to instantiate a new nfsd_file instead of - * opening a new one. + * and @file has FMODE_OPENED set, use it to instantiate a new nfsd_file + * instead of opening a new one. * * Return values: * %nfs_ok - @pnf points to an nfsd_file with its reference