qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 032/104] virtiofsd: passthrough_ll: create new files in calle


From: Dr. David Alan Gilbert
Subject: Re: [PATCH 032/104] virtiofsd: passthrough_ll: create new files in caller's context
Date: Fri, 10 Jan 2020 13:05:00 +0000
User-agent: Mutt/1.13.0 (2019-11-30)

* Daniel P. Berrangé (address@hidden) wrote:
> On Mon, Jan 06, 2020 at 07:08:43PM +0000, Dr. David Alan Gilbert wrote:
> > * Dr. David Alan Gilbert (address@hidden) wrote:
> > > * Daniel P. Berrangé (address@hidden) wrote:
> > > > On Thu, Dec 12, 2019 at 04:37:52PM +0000, Dr. David Alan Gilbert (git) 
> > > > wrote:
> > > > > From: Vivek Goyal <address@hidden>
> > > > > 
> > > > > We need to create files in the caller's context. Otherwise after
> > > > > creating a file, the caller might not be able to do file operations on
> > > > > that file.
> > > > > 
> > > > > Changed effective uid/gid to caller's uid/gid, create file and then
> > > > > switch back to uid/gid 0.
> > > > > 
> > > > > Use syscall(setresuid, ...) otherwise glibc does some magic to change 
> > > > > EUID
> > > > > in all threads, which is not what we want.
> > > > > 
> > > > > Signed-off-by: Vivek Goyal <address@hidden>
> > > > > Signed-off-by: Miklos Szeredi <address@hidden>
> > > > > ---
> > > > >  tools/virtiofsd/passthrough_ll.c | 79 
> > > > > ++++++++++++++++++++++++++++++--
> > > > >  1 file changed, 74 insertions(+), 5 deletions(-)
> > > > > 
> > > > > diff --git a/tools/virtiofsd/passthrough_ll.c 
> > > > > b/tools/virtiofsd/passthrough_ll.c
> > > > > index 68bacb6fc5..0188cd9ad6 100644
> > > > > --- a/tools/virtiofsd/passthrough_ll.c
> > > > > +++ b/tools/virtiofsd/passthrough_ll.c
> > > > 
> > > > 
> > > > > +static int lo_change_cred(fuse_req_t req, struct lo_cred *old)
> > > > > +{
> > > > > +    int res;
> > > > > +
> > > > > +    old->euid = geteuid();
> > > > > +    old->egid = getegid();
> > > > > +
> > > > > +    res = syscall(SYS_setresgid, -1, fuse_req_ctx(req)->gid, -1);
> > > > 
> > > > Do we need to be using  SYS_setres[u,g]id32 instead...
> > > > 
> > > > [quote setresgid(2)]
> > > >        The original Linux setresuid() and setresgid() system  calls
> > > >        supported  only  16-bit  user  and group IDs.  Subsequently,
> > > >        Linux 2.4 added setresuid32() and setresgid32(),  supporting
> > > >        32-bit  IDs.   The glibc setresuid() and setresgid() wrapper
> > > >        functions transparently deal with the variations across ker‐
> > > >        nel versions.
> > > > [/quote]
> > > 
> > > OK, updated.
> > 
> > Hmm hang on; this is messy.  x86-64 only seems to have setresuid
> > where as some architectures have both;  If I'm reading this right, all
> > 64 bit machines have setresuid/gid calling the code that takes the
> > 32bit ID; some have compat entries for 32bit syscalls.
> 
> Oh yuk.
> 
> > I think it's probably more correct to call setresuid here; except
> > for 32 bit platforms - but how do we tell?
> 
> Is it possible to just do an #ifdef SYS_setresgid32 check to see
> if the wider variant exists ?

I've ended up with:

+/*
+ * On some archs, setres*id is limited to 2^16 but they
+ * provide setres*id32 variants that allow 2^32.
+ * Others just let setres*id do 2^32 anyway.
+ */
+#ifdef SYS_setresgid32
+#define OURSYS_setresgid SYS_setresgid32
+#else
+#define OURSYS_setresgid SYS_setresgid
+#endif
+
+#ifdef SYS_setresuid32
+#define OURSYS_setresuid SYS_setresuid32
+#else
+#define OURSYS_setresuid SYS_setresuid
+#endif
+
+/*
+ * Change to uid/gid of caller so that file is created with
+ * ownership of caller.
+ * TODO: What about selinux context?
+ */
+static int lo_change_cred(fuse_req_t req, struct lo_cred *old)
+{
+    int res;
+
+    old->euid = geteuid();
+    old->egid = getegid();
+
+    res = syscall(OURSYS_setresgid, -1, fuse_req_ctx(req)->gid, -1);
+    if (res == -1) {
+        return errno;
+    }
+
+    res = syscall(OURSYS_setresuid, -1, fuse_req_ctx(req)->uid, -1);
+    if (res == -1) {
+        int errno_save = errno;
+
+        syscall(OURSYS_setresgid, -1, old->egid, -1);
+        return errno_save;
+    }

and in the seccomp:

#ifdef __NR_setresgid32
    SCMP_SYS(setresgid32),
#endif
#ifdef __NR_setresuid32
    SCMP_SYS(setresuid32),
#endif

Dave

> 
> Regards,
> Daniel
> -- 
> |: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org         -o-            https://fstop138.berrange.com :|
> |: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
--
Dr. David Alan Gilbert / address@hidden / Manchester, UK




reply via email to

[Prev in Thread] Current Thread [Next in Thread]