From: Max Reitz <mreitz@redhat.com>
To: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: virtio-fs@redhat.com, qemu-devel@nongnu.org,
Stefan Hajnoczi <stefanha@redhat.com>
Subject: Re: [PATCH 8/9] virtiofsd: Optionally fill lo_inode.fhandle
Date: Tue, 8 Jun 2021 13:05:20 +0200 [thread overview]
Message-ID: <92ba88d8-46f3-ffd5-8a22-0c44f40bcc73@redhat.com> (raw)
In-Reply-To: <YL9J2Oyjq2ok0/BM@work-vm>
On 08.06.21 12:43, Dr. David Alan Gilbert wrote:
> * Max Reitz (mreitz@redhat.com) wrote:
>> When the inode_file_handles option is set, try to generate a file handle
>> for new inodes instead of opening an O_PATH FD.
>>
>> Being able to open these again will require CAP_DAC_READ_SEARCH, so the
>> description text tells the user they will also need to specify
>> -o modcaps=+dac_read_search.
>>
>> Generating a file handle returns the mount ID it is valid for. Opening
>> it will require an FD instead. We have mount_fds to map an ID to an FD.
>> get_file_handle() fills the hash map by opening the file we have
>> generated a handle for. To verify that the resulting FD indeed
>> represents the handle's mount ID, we use statx(). Therefore, using file
>> handles requires statx() support.
>>
>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>> ---
>> tools/virtiofsd/helper.c | 3 +
>> tools/virtiofsd/passthrough_ll.c | 170 ++++++++++++++++++++++++--
>> tools/virtiofsd/passthrough_seccomp.c | 1 +
>> 3 files changed, 165 insertions(+), 9 deletions(-)
>>
>> diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c
>> index 5e98ed702b..954f8639e6 100644
>> --- a/tools/virtiofsd/helper.c
>> +++ b/tools/virtiofsd/helper.c
>> @@ -186,6 +186,9 @@ void fuse_cmdline_help(void)
>> " to virtiofsd from guest applications.\n"
>> " default: no_allow_direct_io\n"
>> " -o announce_submounts Announce sub-mount points to the guest\n"
>> + " -o inode_file_handles Use file handles to reference inodes\n"
>> + " instead of O_PATH file descriptors\n"
>> + " (requires -o modcaps=+dac_read_search)\n"
>> );
>> }
>>
>> diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
>> index 793d2c333e..d01f9d3a59 100644
>> --- a/tools/virtiofsd/passthrough_ll.c
>> +++ b/tools/virtiofsd/passthrough_ll.c
>> @@ -190,6 +190,7 @@ struct lo_data {
>> /* An O_PATH file descriptor to /proc/self/fd/ */
>> int proc_self_fd;
>> int user_killpriv_v2, killpriv_v2;
>> + int inode_file_handles;
>> };
>>
>> /**
>> @@ -244,6 +245,10 @@ static const struct fuse_opt lo_opts[] = {
>> { "announce_submounts", offsetof(struct lo_data, announce_submounts), 1 },
>> { "killpriv_v2", offsetof(struct lo_data, user_killpriv_v2), 1 },
>> { "no_killpriv_v2", offsetof(struct lo_data, user_killpriv_v2), 0 },
>> + { "inode_file_handles", offsetof(struct lo_data, inode_file_handles), 1 },
>> + { "no_inode_file_handles",
>> + offsetof(struct lo_data, inode_file_handles),
>> + 0 },
>> FUSE_OPT_END
>> };
>> static bool use_syslog = false;
>> @@ -315,6 +320,108 @@ static int temp_fd_steal(TempFd *temp_fd)
>> }
>> }
>>
>> +/**
>> + * Generate a file handle for the given dirfd/name combination.
>> + *
>> + * If mount_fds does not yet contain an entry for the handle's mount
>> + * ID, (re)open dirfd/name in O_RDONLY mode and add it to mount_fds
>> + * as the FD for that mount ID. (That is the file that we have
>> + * generated a handle for, so it should be representative for the
>> + * mount ID. However, to be sure (and to rule out races), we use
>> + * statx() to verify that our assumption is correct.)
>> + */
>> +static struct lo_fhandle *get_file_handle(struct lo_data *lo,
>> + int dirfd, const char *name)
>> +{
>> + /* We need statx() to verify the mount ID */
>> +#if defined(CONFIG_STATX) && defined(STATX_MNT_ID)
>> + struct lo_fhandle *fh;
>> + int ret;
>> +
>> + if (!lo->use_statx || !lo->inode_file_handles) {
>> + return NULL;
>> + }
>> +
>> + fh = g_new0(struct lo_fhandle, 1);
>> +
>> + fh->handle.handle_bytes = sizeof(fh->padding) - sizeof(fh->handle);
>> + ret = name_to_handle_at(dirfd, name, &fh->handle, &fh->mount_id,
>> + AT_EMPTY_PATH);
>> + if (ret < 0) {
>> + goto fail;
>> + }
>> +
>> + if (pthread_rwlock_rdlock(&mount_fds_lock)) {
>> + goto fail;
>> + }
>> + if (!g_hash_table_contains(mount_fds, GINT_TO_POINTER(fh->mount_id))) {
>> + struct statx stx;
>> + int fd;
>> +
>> + pthread_rwlock_unlock(&mount_fds_lock);
>> +
>> + if (name[0]) {
>> + fd = openat(dirfd, name, O_RDONLY);
> But can't that be a device file or other special file that you must not
> open?
Yes. So I think the right thing to do here is to use O_PATH (which
should be safe), then statx() to find out what we need to know (now not
only the mount ID, but the file type, too), and if it’s safe, we can
then openat(proc_self_fd, str(fd), O_RDONLY) (and close the O_PATH fd).
If it isn’t safe, we just return an error, and the inode gets an O_PATH fd.
Max
next prev parent reply other threads:[~2021-06-08 11:06 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-04 16:13 [PATCH 0/9] virtiofsd: Allow using file handles instead of O_PATH FDs Max Reitz
2021-06-04 16:13 ` [PATCH 1/9] virtiofsd: Add TempFd structure Max Reitz
2021-06-04 16:13 ` [PATCH 2/9] virtiofsd: Use lo_inode_open() instead of openat() Max Reitz
2021-06-04 16:13 ` [PATCH 3/9] virtiofsd: Add lo_inode_fd() helper Max Reitz
2021-06-04 16:13 ` [PATCH 4/9] virtiofsd: Let lo_fd() return a TempFd Max Reitz
2021-06-04 16:13 ` [PATCH 5/9] virtiofsd: Let lo_inode_open() " Max Reitz
2021-06-04 16:13 ` [PATCH 6/9] virtiofsd: Add lo_inode.fhandle Max Reitz
2021-06-04 16:13 ` [PATCH 7/9] virtiofsd: Add inodes_by_handle hash table Max Reitz
2021-06-04 16:13 ` [PATCH 8/9] virtiofsd: Optionally fill lo_inode.fhandle Max Reitz
2021-06-08 10:43 ` Dr. David Alan Gilbert
2021-06-08 11:05 ` Max Reitz [this message]
2021-06-04 16:13 ` [PATCH 9/9] virtiofsd: Add lazy lo_do_find() Max Reitz
2021-06-04 21:17 ` [Virtio-fs] [PATCH 0/9] virtiofsd: Allow using file handles instead of O_PATH FDs Connor Kuehl
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=92ba88d8-46f3-ffd5-8a22-0c44f40bcc73@redhat.com \
--to=mreitz@redhat.com \
--cc=dgilbert@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
--cc=virtio-fs@redhat.com \
/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).