Repositioning of `QubesIncoming` to `tmp`: Interference of SeLinux in `fedora-39` stock template?

/rc/config/rc.local in all my app VMs contains the following:

rm -rf /home/user/QubesIncoming
install -d -o user -g user -m 770 /tmp/QubesIncoming
ln -s /tmp/QubesIncoming /home/user/QubesIncoming
chown -h user:user /home/user/QubesIncoming

what this means is that on starting the AppVM, /home/user/QubesIncoming is replaced with a softlink to /tmp/QubesIncoming, ensuring that everything that has been transfered to that VM during a session will be lost along with other content of /tmp when the VM is shut down - less crud is accumulating.

Following a recent upgrade to fedora-39 as a default base template (in anticipation of the imminent deprecation of fedora-38), this setup is breaking.

While I can e.g. qvm-copy fine to debian-12 based AppVMs, doing so to VMs based on fedora-39 results in this:

$ qvm-copy test.txt 
EOFt 0/0 KB
qfile-unpacker: Fatal error: Error chdir to /home/user/QubesIncoming/disp4011 (error type: Permission denied)

A bit of investigative work leads shows that while on debian-12 based AppVMs the relevant paths look like this:

$ ls -lad /home/user/QubesIncoming
lrwxrwxrwx 1 user user 18 Feb 26 09:25 /home/user/QubesIncoming -> /tmp/QubesIncoming
$ ls -lad /tmp/QubesIncoming
drwxrwx--- 3 user user 4096 Feb 26 10:00 /tmp/QubesIncoming

the equivalent on fedora-39 based machines gives

$ ls -lad /home/user/QubesIncoming
lrwxrwxrwx. 1 user user 18 Feb 26 10:01 /home/user/QubesIncoming -> /tmp/QubesIncoming
$ ls -lad /tmp/QubesIncoming
drwxrwx---. 2 user user 40 Feb 26 10:01 /tmp/QubesIncoming

Note the diverging .(dot) following the access right indicator, which after some reading leads me to believe that SeLinux or its attributes are interfering with the setup.
I have no experience with this at all and am asking for advise on how to tackle this most conservatively without having to forego security benefits from SeLinux usage.

This might be another hint that I’m on the right track. @marmarek writes there: “… having SELinux enabled allows using it […] also for extra hardening of receiving side of qvm-copy.”

Took some time to look into this. It seems you need the following selinux module to be able to copy files with this setup:

module qfile_unpacker 1.0;

require {
	type qubes_qfile_unpacker_t;
	type tmpfs_t;
	type initrc_tmp_t;
	type user_home_t;
	class lnk_file read;
	class dir { add_name create mounton open read search write getattr setattr };
	class file { link open setattr write };
	class filesystem unmount;
}

#============= qubes_qfile_unpacker_t ==============

allow qubes_qfile_unpacker_t tmpfs_t:filesystem unmount;
allow qubes_qfile_unpacker_t user_home_t:lnk_file read;
allow qubes_qfile_unpacker_t initrc_tmp_t:dir { add_name create mounton read search write getattr setattr };
allow qubes_qfile_unpacker_t initrc_tmp_t:dir open;
allow qubes_qfile_unpacker_t initrc_tmp_t:file { link open setattr write };

Paste this into a file named qfile_unpacker.te, build the module with:

checkmodule -M -m -o qfile_unpacker.mod qfile_unpacker.te
semodule_package -o qfile_unpacker.pp -m qfile_unpacker.mod

and then install:

sudo semodule -i qfile_unpacker.pp

Try using qvm-copy from another qube and see if you still get the error.

I’m not a selinux expert, so it could be simpler than that, but this seems to work for me.

2 Likes

Thank you for looking into this. I followed your howto in both the fedora-39 template itself, as well as a AppVM using it, but that didn’t fix the situation. Error identical to before.

You are correct. While testing the module, I manually executed the rc.local script which gave a different value to the rules. Instead of user_tmp_t it should be initrc_tmp_t.

I have updated my previous comment with the correct value to use. Replace it, follow the build/install process again and it should work this time.

THANK YOU. This works (when done in the fedora-39 template).

1 Like

@DVM: could you please guide me through how you figured out what needed allowing? I think I have an equivalent issue when using qvm-copy-to-vm from dom0:

qfile-dom0-agent: File copy: "Permission denied; Last file: <PATH>" (error type: No such file or directory)

I tested with qvm-copy-to-vm and I was able to copy from dom0 to an AppVM using the script you provided and with the module loaded. Perhaps the command in dom0 was incorrect or the module was not loaded in the target qube?

Could you retry with a directory rather than a file, please?

You are right, I can reproduce the error with a directory. I have edited my comment again to fix the problem.

1 Like

Indeed. Works now too. Much appreciated.

1 Like

So now: how does one figure out what functions need allowing when running into a seLinux-prevented operation?

You need to use the audit logs.
First you need to install setroubleshoot-server and then if you get a permission error you can use sealert -l "*" to see what’s wrong and what you need to use.
You will get 2 commands at the top of the output, the first one will create a .pp and .te file with the corresponding rule.
All you have to do next is to use semodule -i for the .pp file and try to do the original action again.
If you still get the error, do the whole process again until it works (the command coming from sealert will append the different rules in the file so you get a complete module when everything works).

1 Like

Thanks again. Just letting you know that your solution also solved a file transfer related problem when using saltfor me (see here) - the lack of seLinux rule allowing this should probably be considered a bug of the fedora-39template…

1 Like