Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new incus module, add required rules to other modules #6

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

mschiff
Copy link
Contributor

@mschiff mschiff commented Dec 6, 2024

This PR adds a new incus module I have developed. It is a first version, which is working for me so far with my current test set which creates, uses and manages (start,stop, restart, destroy) VMs and LXC containers.

The system I use to develop and test the changes is running with profile default/linux/amd64/23.0/hardened/selinux/systemd

As this test set does not cover every feature it is likely that more tweaks and changes need to be added in the future as issues may show up.

If you have comments and recommondations on further edits I am happy to update that PR.

systemd-network-generator.service unit fails without:
  fs_list_tmpfs(systemd_networkd_t)

allow rw to
/sys/fs/cgroup/system.slice/systemd-networkd.service/memory.pressure
  fs_rw_cgroup_files(systemd_networkd_t)

Signed-off-by: Marc Schiffbauer <[email protected]>
@mschiff
Copy link
Contributor Author

mschiff commented Dec 9, 2024

One note regarding MCS: LXC containers currently need to use spc_t (super privileged container) domain in this first version and MCS does not apply to spc_t.

container_t OTOH would work with MCS but was designed for docker/podman process style containers. But e.g. systemd won't boot in a container running as container_t without many more allow rules added. Therefore I think it would be best to create a new incus_lxc_t type which will be quite similar to the virt_lxc_t type from the virt module adapted to work with incusd.

Copy link
Member

@0xC0ncord 0xC0ncord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good so far! Just a couple questions. While we're still working on getting things working I've also left out comments on style.

@@ -47,6 +47,34 @@ tunable_policy(`qemu_full_network',`
corenet_tcp_connect_all_ports(qemu_t)
')

#tunable_policy(`qemu_managed_by_incus',`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably should be a tunable since we're giving some pretty powerful permissions here. qemu_enable_incus or qemu_incus_managed I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. It works except for storage_raw_read_fixed_disk(qemu_t) and storage_raw_read_fixed_disk(qemu_t) which do not seem possible inside a tunable block:

qemu.te:58:ERROR 'syntax error' at token 'typeattribute' on line 6351:                         
#line 58                                       
        typeattribute qemu_t fixed_disk_raw_read;                                              
/usr/bin/checkmodule:  error(s) encountered while parsing configuration                        
make: *** [Makefile:166: tmp/qemu.mod] Error 1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I forgot about this. I don't remember if there's a way to give this access conditionally under normal circumstances.

Comment on lines +75 to +79
# no error, but this AVC:
# scontext="system_u:system_r:incusd_t:s0" # tcontext="system_u:system_r:iptables_t:s0" # class="process"
# perms="sigkill" # comm="incusd" exe="" path=""
# candidate for dontaudit instead?
iptables_admin(incusd_t,system_r)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be changed to iptables_domtrans(incusd_t).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I try I still get:

#============= incusd_t ==============
# audit(1734635352.998:154972):
#  scontext="system_u:system_r:incusd_t:s0" tcontext="system_u:system_r:iptables_t:s0"         
#  class="process" perms="sigkill"
#  comm="incusd" exe="" path=""
#  message="type=AVC msg=audit(1734635352.998:154972): avc:  denied  { sigkill }
#   for  pid=1077723 comm="incusd" scontext=system_u:system_r:incusd_t:s0
#   tcontext=system_u:system_r:iptables_t:s0 tclass=process permissive=0 "
allow incusd_t iptables_t:process sigkill;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll probably need to add new interfaces to iptables for these missing rules then. We can't use iptables_admin() because it requires passing in system_r which the incus module doesn't own.

It works, sure, but it's unpalatable for usptream.

Comment on lines 121 to 122
# watch /dev/hugepages
files_watch_all_dirs(incusd_t)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this just for hugepages? We can create a new interface for it like fs_watch_hugetlbfs_dirs().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the line noe because I cannot reproduce this denial anymore. Maybe due to an incus update, not sure. But if it reappears I will add that interface for it.

Comment on lines +192 to +195
# incusd needs support to label VM files before launching
# until then, VM files will unfortunately be unlabeled
kernel_manage_unlabeled_dirs(incusd_t)
kernel_manage_unlabeled_files(incusd_t)
kernel_manage_unlabeled_symlinks(incusd_t)
kernel_mounton_unlabeled_dirs(incusd_t)
files_search_default(incusd_t)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this fuctionality currently exist in incus?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incus is still missing some selinux awareness, e.g. label some objects properly before launching a qemu VM. Until it will get support for that we can remove these kernel_manage_* and (I guess) files_search_default again.

Does this answer your question?

Some more details:

# audit(1734698529.636:163140):
#  scontext="system_u:system_r:incusd_t:s0" tcontext="system_u:object_r:unlabeled_t:s0"
#  class="dir" perms="getattr"
#  comm="incusd" exe="" path=""
#  message="type=AVC msg=audit(1734698529.636:163140): avc:  denied  { getattr }
#   for  pid=1166765 comm="incusd" path="/var/lib/incus/storage-
#   pools/default/virtual-machines/vm1" dev="zfs" ino=34
#   scontext=system_u:system_r:incusd_t:s0
#   tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=0 "
allow incusd_t unlabeled_t:dir getattr;

(sysadm_r)@host ~ # mount|grep vm1
zdata/incus/virtual-machines/vm1 on /var/lib/incus/storage-pools/default/virtual-machines/vm1 type zfs (rw,relatime,seclabel,xattr,posixacl,casesensitive)
zdata/incus/virtual-machines/vm1 on /var/lib/incus/devices/vm1/config.mount type zfs (ro,relatime,seclabel,xattr,posixacl,casesensitive)

(sysadm_r)@host ~ # ls -lZR /var/lib/incus/virtual-machines
/var/lib/incus/virtual-machines:
total 9
lrwxrwxrwx. 1 root root system_u:object_r:container_var_lib_t:s0 57 20. Dez 13:44 vm1 -> /var/lib/incus/storage-pools/default/virtual-machines/vm1
(sysadm_r)@host ~/selinux/local # ls -lZRd /var/lib/incus/virtual-machines/vm1
lrwxrwxrwx. 1 root root system_u:object_r:container_var_lib_t:s0 57 20. Dez 13:44 /var/lib/incus/virtual-machines/vm1 -> /var/lib/incus/storage-pools/default/virtual-machines/vm1
(sysadm_r)@host ~ # 
(sysadm_r)@host ~ # ls -lZR /var/lib/incus/storage-pools/default/virtual-machines/vm1
/var/lib/incus/storage-pools/default/virtual-machines/vm1:
ls: cannot read symbolic link '/var/lib/incus/storage-pools/default/virtual-machines/vm1/qemu.nvram': Permission denied
total 73
-rw-r--r--. 1 root   root system_u:object_r:unlabeled_t:s0    688 20. Dez 13:44 agent-client.crt
-rw-------. 1 root   root system_u:object_r:unlabeled_t:s0    288 20. Dez 13:44 agent-client.key
-rw-r--r--. 1 root   root system_u:object_r:unlabeled_t:s0    725 20. Dez 13:44 agent.crt
-rw-------. 1 root   root system_u:object_r:unlabeled_t:s0    288 20. Dez 13:44 agent.key
-r--------. 1 root   root system_u:object_r:unlabeled_t:s0   2762 20. Dez 13:44 backup.yaml
dr-x------. 6 nobody root system_u:object_r:unlabeled_t:s0     14 20. Dez 13:44 config
-rw-------. 1 nobody root system_u:object_r:unlabeled_t:s0 540672 20. Dez 13:44 edk2-i386-vars.fd
-rw-r--r--. 1 root   root system_u:object_r:unlabeled_t:s0    526 20. Dez 08:48 metadata.yaml
lrwxrwxrwx. 1 root   root system_u:object_r:unlabeled_t:s0     17 20. Dez 13:44 qemu.nvram
drwxr-xr-x. 2 root   root system_u:object_r:unlabeled_t:s0      4 20. Dez 08:48 templates

total 13718
-r--------. 1 nobody root system_u:object_r:unlabeled_t:s0        2 20. Dez 13:44 agent-mounts.json
-rw-r--r--. 1 nobody root system_u:object_r:unlabeled_t:s0      818 20. Dez 13:44 agent.conf
-r--------. 1 nobody root system_u:object_r:unlabeled_t:s0      725 20. Dez 13:44 agent.crt
-r--------. 1 nobody root system_u:object_r:unlabeled_t:s0      288 20. Dez 13:44 agent.key
dr-x------. 2 nobody root system_u:object_r:unlabeled_t:s0        3 20. Dez 13:44 files
-r-x------. 1 nobody root system_u:object_r:unlabeled_t:s0 21724049 12. Dez 17:08 incus-agent
-rwx------. 1 nobody root system_u:object_r:unlabeled_t:s0     1302 20. Dez 13:44 install.sh
lrwxrwxrwx. 1 root   root system_u:object_r:unlabeled_t:s0       11 20. Dez 13:44 lxd-agent
dr-x------. 2 nobody root system_u:object_r:unlabeled_t:s0        2 20. Dez 13:44 nics
-r--------. 1 nobody root system_u:object_r:unlabeled_t:s0      688 20. Dez 13:44 server.crt
dr-x------. 2 nobody root system_u:object_r:unlabeled_t:s0        4 20. Dez 13:44 systemd
dr-x------. 2 nobody root system_u:object_r:unlabeled_t:s0        3 20. Dez 13:44 udev

/var/lib/incus/storage-pools/default/virtual-machines/vm1/config/files:
total 5
-rw-r--r--. 1 nobody root system_u:object_r:unlabeled_t:s0 526 20. Dez 13:44 metadata.yaml

/var/lib/incus/storage-pools/default/virtual-machines/vm1/config/nics:
total 0

/var/lib/incus/storage-pools/default/virtual-machines/vm1/config/systemd:
total 9
-r-x------. 1 nobody root system_u:object_r:unlabeled_t:s0 1570 20. Dez 13:44 incus-agent-setup
-r--------. 1 nobody root system_u:object_r:unlabeled_t:s0  419 20. Dez 13:44 incus-agent.service

/var/lib/incus/storage-pools/default/virtual-machines/vm1/config/udev:
total 5
-r--------. 1 nobody root system_u:object_r:unlabeled_t:s0 109 20. Dez 13:44 99-incus-agent.rules

/var/lib/incus/storage-pools/default/virtual-machines/vm1/templates:
total 9
-rw-r--r--. 1 root root system_u:object_r:unlabeled_t:s0  21 20. Dez 08:48 hostname.tpl
-rw-r--r--. 1 root root system_u:object_r:unlabeled_t:s0 140 20. Dez 08:48 hosts.tpl


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see now. Thanks!

Also good to see that there is active discussion on this over in the incus repo: lxc/incus#1037

files_mmap_read_usr_files(zfs_t)

# auto-snapshots through systemd-timer not working without this
allow zfs_t zfs_exec_t:file execute_no_trans;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can_exec(zfs_t, zfs_exec_t)

@0xC0ncord
Copy link
Member

One note regarding MCS: LXC containers currently need to use spc_t (super privileged container) domain in this first version and MCS does not apply to spc_t.

container_t OTOH would work with MCS but was designed for docker/podman process style containers. But e.g. systemd won't boot in a container running as container_t without many more allow rules added. Therefore I think it would be best to create a new incus_lxc_t type which will be quite similar to the virt_lxc_t type from the virt module adapted to work with incusd.

I think the best way to support this would be to create a type using container_domain_template() if we can. This will set up a process type with some very barebones functionality that most containers require but without any of the "fancy" things (even networking). Take a look at container_kvm_t as an example.

for reading compatibility file /usr/share/zfs/compatibility.d/openzfs-2.2
-rw-r--r--. 1 root root system_u:object_r:usr_t:s0 584 30. Aug 01:15 /usr/share/zfs/compatibility.d/openzfs-2.2

files_read_usr_files(zfs_t)
files_mmap_read_usr_files(zfs_t)

 auto-snapshots through systemd-timer not working without this:
  scontext="system_u:system_r:zfs_t:s0" tcontext="system_u:object_r:zfs_exec_t:s0"
  class="file" perms="execute_no_trans"
  comm="env" exe="" path=""
  message="type=AVC msg=audit(1726998333.913:106): avc:  denied  {
   execute_no_trans } for  pid=1708 comm="env" path="/usr/bin/zpool" dev="zfs"
   ino=405615 scontext=system_u:system_r:zfs_t:s0
   tcontext=system_u:object_r:zfs_exec_t:s0 tclass=file permissive=0 "

allow zfs_t zfs_exec_t:file execute_no_trans;

Signed-off-by: Marc Schiffbauer <[email protected]>
Signed-off-by: Marc Schiffbauer <[email protected]>
Signed-off-by: Marc Schiffbauer <[email protected]>
and add rule to other modules taht need to talk
to incusd

Signed-off-by: Marc Schiffbauer <[email protected]>
this turns the previous optional block into a tunable
which defaults to off

Signed-off-by: Marc Schiffbauer <[email protected]>
This is not reproducable anymore in current incus version

Signed-off-by: Marc Schiffbauer <[email protected]>
@0xC0ncord
Copy link
Member

One note regarding MCS: LXC containers currently need to use spc_t (super privileged container) domain in this first version and MCS does not apply to spc_t.

container_t OTOH would work with MCS but was designed for docker/podman process style containers. But e.g. systemd won't boot in a container running as container_t without many more allow rules added. Therefore I think it would be best to create a new incus_lxc_t type which will be quite similar to the virt_lxc_t type from the virt module adapted to work with incusd.

I did some more digging into this and these rules probably need to be added to a new container_init_t type. This type already exists in container-selinux and its purpose is to allow systemd and other init systems to boot in a container as you describe. We don't have this type in refpolicy (and Gentoo policy) yet.

Also the reason why you're seeing all containers run as spc_t is because of the way the policy is written. Container engines will need to use setexeccon() when spawning a container process, otherwise the policy does an automatic transition to spc_t by design. If a user wants a specific SELinux context for the container to run in, there's usually a way to tell the container engine to do that (e.g. podman uses --context=) which will do the same thing, but with a manually specified context.

Comment on lines +80 to +82
# this is not possible as a tunable
storage_raw_read_fixed_disk(qemu_t)
storage_raw_write_fixed_disk(qemu_t)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so we need to enable this like so:

storage_raw_read_fixed_disk_cond(qemu_t, qemu_incus_managed)
storage_raw_write_fixed_disk_cond(qemu_t, qemu_incus_managed)

The storage_raw_write_fixed_disk_cond interface doesn't exist in the policy so it needs to be added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants