<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
<div>Thanks for this great explanation, now everything is more clear to me.<br></div><div dir="auto"><br></div><div dir="auto">Basically this problem happens every time there is permissions configuration just a little bit more advanced and at the moment there isn't an on the fly solution that doesn't need kernel patching and recompiling.<br></div><div dir="auto"><br></div><div dir="auto">Good to know.<br></div><div><br></div><div><br></div><div>2 giu 2021, 10:32 da chirantan@chromium.org:<br></div><blockquote class="tutanota_quote" style="border-left: 1px solid #93A3B8; padding-left: 10px; margin-left: 5px;"><div>On Wed, Jun 2, 2021 at 1:01 AM <tecufanujacu@tutanota.com> wrote:<br></div><blockquote><div><br></div><div>Hello to everyone,<br></div><div><br></div><div>I'm trying virtiofsd with proxmox from few weeks and I noticed a problem, virtiofsd doesn't garant write access at users allowed by group permission.<br></div><div><br></div><div>The virtiofsd bin included in proxmox is v 7.32, but I have also tested the bins compiled from source from stable branch (v7.27) and dev branch (v7.33), and I also have tested the bin virtiofsd-rs. Always same problem.<br></div><div><br></div><div>I opened an issue on gitlab and I asked in the proxmox forum but with almost zero interaction. Seems to me that virtiofsd isn't a lot used. Someone suggested me to write in the mailinglist for these technical things and here I am.<br></div><div><br></div><div>To better make understand what problem I'm noticing I link the issue opened in the gitlab in which I have reported a lot of useful info and logs with a good formatting:<br></div><div>https://gitlab.com/qemu-project/qemu/-/issues/368<br></div><div><br></div><div>To me seems really strange what is happening, am I doing some error or this really is a virtiofsd bug?<br></div></blockquote><div><br></div><div>I'm pretty sure this is a virtiofsd issue because we ran into the same<br></div><div>problem on crosvm.  The issue is that the server changes its uid/gid<br></div><div>to the uid/gid in the fuse context before making the syscall.  This<br></div><div>ensures that the file/directory appears atomically with the correct<br></div><div>metadata.  However, this causes an EACCES error when the following<br></div><div>conditions are<br></div><div>met:<br></div><div><br></div><div>* The parent directory has g+rw permissions with gid A<br></div><div>* The process has gid B but has A in its list of supplementary groups<br></div><div><br></div><div>In this case the fuse context only contains gid B, which doesn't have<br></div><div>permission to modify the parent directory.<br></div><div><br></div><div>There are a couple of ways to fix this problem:<br></div><div><br></div><div>The first one we tried was to split file/directory creation into 2<br></div><div>stages [1].  Basically for files we first create a temporary with<br></div><div>O_TMPFILE and then initialize the metadata before linking it into the<br></div><div>directory tree.  The main issue with this is that we're duplicating<br></div><div>the work that kernel already does on open and turning a single syscall<br></div><div>in the VM into several syscalls on the host, which adds a significant<br></div><div>amount of latency.  You also have to deal with a bunch of esoteric<br></div><div>corner cases for file systems that the kernel would normally just<br></div><div>handle automatically [2][3].  For directories, there is no O_TMPFILE<br></div><div>equivalent so we had to do a gross hack of creating a directory with a<br></div><div>random name and then renaming it to the correct one once all the<br></div><div>metadata was properly initialized.  In theory you could create the<br></div><div>directory in a separate "work dir" first but you have to be careful if<br></div><div>the original directory uses selinux.  From what I understand, rename<br></div><div>preserves the security context so to ensure the security context is<br></div><div>properly inherited from the parent directory you need to create a new<br></div><div>directory anyway.  Or figure out what the correct context should be<br></div><div>and set it in the work dir before the rename.<br></div><div><br></div><div>The second solution, which is also what we're using now, is to set the<br></div><div>SECBIT_NO_SETUID_FIXUP flag.  This flag prevents the kernel from<br></div><div>dropping caps when the process changes its uid/gid so the permission<br></div><div>checks are skipped as long as the server has the appropriate<br></div><div>capabilities (CAP_DAC_OVERRIDE, I think?).  Doing this lets us drop<br></div><div>all the special handling code and just go back to making a single<br></div><div>syscall and letting the kernel figure out the rest [4].  The crosvm fs<br></div><div>device always runs as root in a user namespace with the proper caps so<br></div><div>this works for us but obviously will not work if virtiofsd doesn't<br></div><div>have the caps to begin with.  At that point the first option may be<br></div><div>the only choice.<br></div><div><br></div><div>I guess a third option is to change the fuse protocol so that it also<br></div><div>includes the supplementary groups of the calling process.  Then the<br></div><div>server can also set its supplementary groups the same way before<br></div><div>making the syscall.  Merging the necessary changes into the kernel is<br></div><div>left as an exercise for the reader ;-)<br></div><div><br></div><div><br></div><div>Chirantan<br></div><div><br></div><div>[1]: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2217534<br></div><div>[2]: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2253493<br></div><div>[3]: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2260253<br></div><div>[4]: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2684067<br></div></blockquote><div dir="auto"><br></div>  </body>
</html>