[Virtio-fs] [PATCH v2 1/2] virtiofsd: Fix xattr operations

misono.tomohiro at fujitsu.com misono.tomohiro at fujitsu.com
Fri Jan 31 01:57:21 UTC 2020


> > Current virtiofsd has problems about xattr operations and they does
> > not work properly for directory/symlink/special file.
> >
> > The fundamental cause is that virtiofsd uses openat() + f...xattr()
> > systemcalls for xattr operation but we should not open symlink/special
> > file in the daemon. Therefore the function is restricted.
> >
> > Fix this problem by:
> >  1. during setup of each thread, call unshare(CLONE_FS) so that chdir
> >     would not affect other threads
> >  2. in xattr operations (i.e. lo_getxattr), use
> >     fchdir(proc_loot_fd) + ...xattr() + fchdir(root.fd)
> >     instead of openat() + f...xattr() to avoid open files
> >
> > With this patch, xfstests generic/062 passes on virtiofs.
> > This fix is suggested by Miklos Szeredi and Stefan Hajnoczi.
> >
> > Signed-off-by: Misono Tomohiro <misono.tomohiro at jp.fujitsu.com>
> > ---
> >  tools/virtiofsd/fuse_virtio.c    |  13 ++++
> >  tools/virtiofsd/passthrough_ll.c | 100 +++++++++++++++++++------------
> >  tools/virtiofsd/seccomp.c        |  10 ++--
> >  3 files changed, 81 insertions(+), 42 deletions(-)
> >
> > diff --git a/tools/virtiofsd/fuse_virtio.c
> > b/tools/virtiofsd/fuse_virtio.c index 1aac6b8687..ad03a7dcc0 100644
> > --- a/tools/virtiofsd/fuse_virtio.c
> > +++ b/tools/virtiofsd/fuse_virtio.c
> > @@ -463,6 +463,8 @@ err:
> >      return ret;
> >  }
> >
> > +static __thread bool clone_fs_called;
> > +
> >  /* Process one FVRequest in a thread pool */  static void
> > fv_queue_worker(gpointer data, gpointer user_data)  { @@ -478,6
> > +480,17 @@ static void fv_queue_worker(gpointer data, gpointer
> > user_data)
> >
> >      assert(se->bufsize > sizeof(struct fuse_in_header));
> >
> > +    if (!clone_fs_called) {
> > +        int ret;
> > +
> > +        /* unshare FS for xattr operation */
> > +        ret = unshare(CLONE_FS);
> > +        /* should not fail */
> > +        assert(ret == 0);
> > +
> > +        clone_fs_called = true;
> > +    }
> > +
> >      /*
> >       * An element contains one request and the space to send our response
> >       * They're spread over multiple descriptors in a scatter/gather
> > set diff --git a/tools/virtiofsd/passthrough_ll.c
> > b/tools/virtiofsd/passthrough_ll.c
> > index f0093ab84e..6bcc33e0eb 100644
> > --- a/tools/virtiofsd/passthrough_ll.c
> > +++ b/tools/virtiofsd/passthrough_ll.c
> > @@ -2362,6 +2362,7 @@ static void lo_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
> >      ssize_t ret;
> >      int saverr;
> >      int fd = -1;
> > +    bool dir_changed = false;
> >
> >      inode = lo_inode(req, ino);
> >      if (!inode) {
> > @@ -2377,17 +2378,14 @@ static void lo_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
> >      fuse_log(FUSE_LOG_DEBUG, "lo_getxattr(ino=%" PRIu64 ", name=%s size=%zd)\n",
> >               ino, name, size);
> >
> > -    if (inode->is_symlink) {
> > -        /* Sorry, no race free way to getxattr on symlink. */
> > -        saverr = EPERM;
> > -        goto out;
> > -    }
> > -
> >      sprintf(procname, "%i", inode->fd);
> > -    fd = openat(lo->proc_self_fd, procname, O_RDONLY);
> > -    if (fd < 0) {
> > +    ret = fchdir(lo->proc_self_fd);
> > +    if (ret < 0) {
> > +        /* should not happen */
> > +        fuse_log(FUSE_LOG_ERR, "lo_getxattr: fail fchdir to
> > + proc_self_fd\n");
> >          goto out_err;
> >      }
> > +    dir_changed = true;
> >
> >      if (size) {
> >          value = malloc(size);
> 
> I am wondering, is it better to allocate memory first (if need be) and then do fchdir(). If memory allocation fails, we can return
> error right away without having to do fchdir() twice.
> 
> Also do we need dir_changed variable? I think if we organize labels properly, we should be able to get rid of this dir_changed
> variable.
> 
> Same comments apply to lo_listxattr() as well.

Sounds reasonable, I will refactor the code.
Misono





More information about the Virtio-fs mailing list