[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250222044130.GO1977892@ZenIV>
Date: Sat, 22 Feb 2025 04:41:30 +0000
From: Al Viro <viro@...iv.linux.org.uk>
To: NeilBrown <neilb@...e.de>
Cc: Christian Brauner <brauner@...nel.org>, Jan Kara <jack@...e.cz>,
Miklos Szeredi <miklos@...redi.hu>, Xiubo Li <xiubli@...hat.com>,
Ilya Dryomov <idryomov@...il.com>,
Richard Weinberger <richard@....at>,
Anton Ivanov <anton.ivanov@...bridgegreys.com>,
Johannes Berg <johannes@...solutions.net>,
Trond Myklebust <trondmy@...nel.org>,
Anna Schumaker <anna@...nel.org>,
Chuck Lever <chuck.lever@...cle.com>,
Jeff Layton <jlayton@...nel.org>,
Olga Kornievskaia <okorniev@...hat.com>,
Dai Ngo <Dai.Ngo@...cle.com>, Tom Talpey <tom@...pey.com>,
Sergey Senozhatsky <senozhatsky@...omium.org>,
linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-cifs@...r.kernel.org, linux-nfs@...r.kernel.org,
linux-um@...ts.infradead.org, ceph-devel@...r.kernel.org,
netfs@...ts.linux.dev
Subject: Re: [PATCH 5/6] nfs: change mkdir inode_operation to return
alternate dentry if needed.
On Fri, Feb 21, 2025 at 10:36:34AM +1100, NeilBrown wrote:
> nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
> {
> struct posix_acl *default_acl, *acl;
> @@ -612,15 +612,18 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
> dentry = d_alias;
>
> status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl);
> + if (status && d_alias)
> + dput(d_alias);
>
> - dput(d_alias);
> out_release_acls:
> posix_acl_release(acl);
> posix_acl_release(default_acl);
> out:
> nfs3_free_createdata(data);
> dprintk("NFS reply mkdir: %d\n", status);
> - return status;
> + if (status)
> + return ERR_PTR(status);
> + return d_alias;
Ugh... That's really hard to follow - you are leaving a dangling
reference in d_alias textually upstream of using that variable.
The only reason it's not a bug is that dput() is reachable only
with status && d_alias and that guarantees that we'll
actually go away on if (status) return ERR_PTR(status).
Worse, you can reach 'out:' with d_alias uninitialized. Yes,
all such branches happen with status either still unmodified
since it's initialization (which is non-zero) or under
if (status), so again, that return d_alias; is unreachable.
So the code is correct, but it's really asking for trouble down
the road.
BTW, dput(NULL) is guaranteed to be a no-op...
Powered by blists - more mailing lists