linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: Amir Goldstein <amir73il@gmail.com>
Cc: Christian Brauner <brauner@kernel.org>,
	Aleksa Sarai <cyphar@cyphar.com>,
	 Chuck Lever <chuck.lever@oracle.com>,
	linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org
Subject: Re: [RFC PATCH 1/2] fs: name_to_handle_at() support for connectable file handles
Date: Fri, 20 Sep 2024 09:36:17 +0200	[thread overview]
Message-ID: <1f8eb177bf7aa09db96c32451a14a8cdb7e31649.camel@kernel.org> (raw)
In-Reply-To: <9ab958370d5210394e5e6beaad0e788d71c42834.camel@kernel.org>

On Fri, 2024-09-20 at 09:13 +0200, Jeff Layton wrote:
> On Thu, 2024-09-19 at 16:06 +0200, Amir Goldstein wrote:
> > nfsd encodes "connectable" file handles for the subtree_check feature.
> > So far, userspace nfs server could not make use of this functionality.
> > 
> > Introduce a new flag AT_HANDLE_CONNECTABLE to name_to_handle_at(2).
> > When used, the encoded file handle is "connectable".
> > 
> > Note that decoding a "connectable" file handle with open_by_handle_at(2)
> > is not guarandteed to return a "connected" fd (i.e. fd with known path).
> > A new opt-in API would be needed to guarantee a "connected" fd.
> > 
> > Signed-off-by: Amir Goldstein <amir73il@gmail.com>
> > ---
> >  fs/fhandle.c               | 24 ++++++++++++++++++++----
> >  include/uapi/linux/fcntl.h |  1 +
> >  2 files changed, 21 insertions(+), 4 deletions(-)
> > 
> > diff --git a/fs/fhandle.c b/fs/fhandle.c
> > index 8cb665629f4a..956d9b25d4f7 100644
> > --- a/fs/fhandle.c
> > +++ b/fs/fhandle.c
> > @@ -31,6 +31,11 @@ static long do_sys_name_to_handle(const struct path *path,
> >  	if (!exportfs_can_encode_fh(path->dentry->d_sb->s_export_op, fh_flags))
> >  		return -EOPNOTSUPP;
> >  
> > +	/* Do not encode a connectable handle for a disconnected dentry */
> > +	if (fh_flags & EXPORT_FH_CONNECTABLE &&
> > +	    path->dentry->d_flags & DCACHE_DISCONNECTED)
> > +		return -EACCES;
> > +
> 
> I'm not sure about EACCES here. That implies that if you had the right
> creds then this would work. DCACHE_DISCONNECTED has nothing to do with
> permissions though. Maybe -EINVAL instead since getting a disconnected
> dentry here would imply that @path is somehow bogus?
> 
> Given how this function is used, will we ever see a disconnected dentry
> here? The path comes from userland in this case, so I don't think it
> can ever be disconnected. Maybe a WARN_ON_ONCE or pr_warn would be
> appropriate in this case too?
> 

Oh, I guess you can get a disconnected dentry here.

You could call open_by_handle_at() for a directory fh, and then pass
that into name_to_handle_at().

Either way, this API scares me since it seems like it can just randomly
fail, depending on the state of the dcache. That's the worst-case
scenario for an API.

If you want to go through with this, you'll need to carefully document
what's required to make this work properly, as this has some
significant footguns.

 
> >  	if (copy_from_user(&f_handle, ufh, sizeof(struct file_handle)))
> >  		return -EFAULT;
> >  
> > @@ -45,7 +50,7 @@ static long do_sys_name_to_handle(const struct path *path,
> >  	/* convert handle size to multiple of sizeof(u32) */
> >  	handle_dwords = f_handle.handle_bytes >> 2;
> >  
> > -	/* we ask for a non connectable maybe decodeable file handle */
> > +	/* Encode a possibly decodeable/connectable file handle */
> >  	retval = exportfs_encode_fh(path->dentry,
> >  				    (struct fid *)handle->f_handle,
> >  				    &handle_dwords, fh_flags);
> > @@ -109,15 +114,26 @@ SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char __user *, name,
> >  {
> >  	struct path path;
> >  	int lookup_flags;
> > -	int fh_flags;
> > +	int fh_flags = 0;
> >  	int err;
> >  
> >  	if (flag & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH | AT_HANDLE_FID |
> > -		     AT_HANDLE_MNT_ID_UNIQUE))
> > +		     AT_HANDLE_MNT_ID_UNIQUE | AT_HANDLE_CONNECTABLE))
> > +		return -EINVAL;
> > +
> > +	/*
> > +	 * AT_HANDLE_FID means there is no intention to decode file handle
> > +	 * AT_HANDLE_CONNECTABLE means there is an intention to decode a
> > +	 * connected fd (with known path), so these flags are conflicting.
> > +	 */
> > +	if (flag & AT_HANDLE_CONNECTABLE && flag & AT_HANDLE_FID)
> >  		return -EINVAL;
> > +	else if (flag & AT_HANDLE_FID)
> > +		fh_flags |= EXPORT_FH_FID;
> > +	else if (flag & AT_HANDLE_CONNECTABLE)
> > +		fh_flags |= EXPORT_FH_CONNECTABLE;
> >  
> >  	lookup_flags = (flag & AT_SYMLINK_FOLLOW) ? LOOKUP_FOLLOW : 0;
> > -	fh_flags = (flag & AT_HANDLE_FID) ? EXPORT_FH_FID : 0;
> >  	if (flag & AT_EMPTY_PATH)
> >  		lookup_flags |= LOOKUP_EMPTY;
> >  	err = user_path_at(dfd, name, lookup_flags, &path);
> > diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h
> > index 87e2dec79fea..56ff2100e021 100644
> > --- a/include/uapi/linux/fcntl.h
> > +++ b/include/uapi/linux/fcntl.h
> > @@ -153,6 +153,7 @@
> >  					   object identity and may not be
> >  					   usable with open_by_handle_at(2). */
> >  #define AT_HANDLE_MNT_ID_UNIQUE	0x001	/* Return the u64 unique mount ID. */
> > +#define AT_HANDLE_CONNECTABLE	0x002	/* Request a connectable file handle */
> >  
> >  #if defined(__KERNEL__)
> >  #define AT_GETATTR_NOSEC	0x80000000
> 
> -- 
> Jeff Layton <jlayton@kernel.org>
> 

-- 
Jeff Layton <jlayton@kernel.org>

  reply	other threads:[~2024-09-20  7:36 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-19 14:06 [RFC PATCH 0/2] API for exporting connectable file handles to userspace Amir Goldstein
2024-09-19 14:06 ` [RFC PATCH 1/2] fs: name_to_handle_at() support for connectable file handles Amir Goldstein
2024-09-20  7:13   ` Jeff Layton
2024-09-20  7:36     ` Jeff Layton [this message]
2024-09-20  8:40       ` Amir Goldstein
2024-09-19 14:06 ` [RFC PATCH 2/2] fs: open_by_handle_at() support for decoding " Amir Goldstein
2024-09-20 16:02   ` Jeff Layton
2024-09-20 16:38     ` Amir Goldstein
2024-09-21  5:33       ` Jeff Layton
2024-09-21  9:13         ` Aleksa Sarai
2024-09-21 10:25         ` Amir Goldstein
2024-09-21  9:15       ` Aleksa Sarai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1f8eb177bf7aa09db96c32451a14a8cdb7e31649.camel@kernel.org \
    --to=jlayton@kernel.org \
    --cc=amir73il@gmail.com \
    --cc=brauner@kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=cyphar@cyphar.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).