[libvirt PATCH 00/13] selinux: introduce sVirt policy and build

This is an extension of https://listman.redhat.com/archives/libvir-list/2021-July/msg00167.html The original patches from that series are unchanged apart from the commit message, and tweak to the min fedora version in the RPM. I then include various refactors/cleanups. On Fedora 34 I notice the following: ../src/security/selinux/virt.te:579: Warning: fs_rw_anon_inodefs_files(virtd_t) has been deprecated. All calls can be safely removed. ../src/security/selinux/virt.te:580: Warning: fs_list_inotifyfs(virtd_t) has been deprecated. All calls can be safely removed. ../src/security/selinux/virt.te:985: Warning: fs_rw_anon_inodefs_files(virt_domain) has been deprecated. All calls can be safely removed. ../src/security/selinux/virt.te:1520: Warning: fs_list_inotifyfs(svirt_sandbox_domain) has been deprecated. All calls can be safely removed. assuming those warnings are correct, we can delete a few things from the policy, but that's not done here. Daniel P. Berrangé (10): selinux: remove redundant use of 'set_variable' function selinux: move selinux policy build helper to scripts directory selinux: don't hardcode paths to selinux tools selinux: don't hardcode policy include files directory rpm: move logic for setting selinux policy variables rpm: rename selinux variables to improve clarity selinux: introduce meson option for selinux policy install selinux: remove duplicate sources list for policy scripts: use variables for cli args in selinux helper scripts: factor repeated path joins from selinux helper Nikola Knazekova (1): security: add SELinux policy for virt Vit Mojzis (2): selinux: introduce build, install, packaging for selinux policy Install selinux-policy-devel in test environment ci/containers/centos-8.Dockerfile | 1 + ci/containers/centos-stream-8.Dockerfile | 1 + ci/containers/fedora-33.Dockerfile | 1 + ci/containers/fedora-34.Dockerfile | 1 + .../fedora-rawhide-cross-mingw32.Dockerfile | 1 + .../fedora-rawhide-cross-mingw64.Dockerfile | 1 + ci/containers/fedora-rawhide.Dockerfile | 1 + libvirt.spec.in | 100 + meson.build | 1 + meson_options.txt | 2 + scripts/meson.build | 1 + scripts/selinux-compile-policy.py | 156 ++ src/security/meson.build | 2 + src/security/selinux/mcs/meson.build | 17 + src/security/selinux/meson.build | 45 + src/security/selinux/mls/meson.build | 17 + src/security/selinux/virt.fc | 111 + src/security/selinux/virt.if | 1984 ++++++++++++++++ src/security/selinux/virt.te | 2078 +++++++++++++++++ 19 files changed, 4521 insertions(+) create mode 100755 scripts/selinux-compile-policy.py create mode 100644 src/security/selinux/mcs/meson.build create mode 100644 src/security/selinux/meson.build create mode 100644 src/security/selinux/mls/meson.build create mode 100644 src/security/selinux/virt.fc create mode 100644 src/security/selinux/virt.if create mode 100644 src/security/selinux/virt.te -- 2.31.1

From: Nikola Knazekova <nknazeko@redhat.com> SELinux policy was created for: Hypervisor drivers: - virtqemud (QEMU/KVM) - virtlxcd (LXC) - virtvboxd (VirtualBox) Secondary drivers: - virtstoraged (host storage mgmt) - virtnetworkd (virtual network mgmt) - virtinterface (network interface mgmt) - virtnodedevd (physical device mgmt) - virtsecretd (security credential mgmt) - virtnwfilterd (ip[6]tables/ebtables mgmt) - virtproxyd (proxy daemon) SELinux policy for virtvxz and virtxend has not been created yet, because I wasn't able to reproduce AVC messages. These drivers run in unconfined_domain until the AVC messages are reproduced internally and policy for these drivers is made. Signed-off-by: Nikola Knazekova <nknazeko@redhat.com> --- src/security/selinux/virt.fc | 111 ++ src/security/selinux/virt.if | 1984 ++++++++++++++++++++++++++++++++ src/security/selinux/virt.te | 2078 ++++++++++++++++++++++++++++++++++ 3 files changed, 4173 insertions(+) create mode 100644 src/security/selinux/virt.fc create mode 100644 src/security/selinux/virt.if create mode 100644 src/security/selinux/virt.te diff --git a/src/security/selinux/virt.fc b/src/security/selinux/virt.fc new file mode 100644 index 0000000000..554e1094d9 --- /dev/null +++ b/src/security/selinux/virt.fc @@ -0,0 +1,111 @@ +HOME_DIR/\.libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.cache/libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.cache/libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.config/libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.config/libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/VirtualMachines(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/VirtualMachines/isos(/.*)? gen_context(system_u:object_r:virt_content_t,s0) +HOME_DIR/\.local/share/libvirt/images(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.local/share/libvirt/boot(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) + +/etc/libvirt -d gen_context(system_u:object_r:virt_etc_t,s0) +/etc/libvirt/virtlogd\.conf -- gen_context(system_u:object_r:virtlogd_etc_t,s0) +/etc/libvirt/[^/]* -- gen_context(system_u:object_r:virt_etc_t,s0) +/etc/libvirt/[^/]* -d gen_context(system_u:object_r:virt_etc_rw_t,s0) +/etc/libvirt/.*/.* gen_context(system_u:object_r:virt_etc_rw_t,s0) +/etc/rc\.d/init\.d/libvirtd -- gen_context(system_u:object_r:virtd_initrc_exec_t,s0) +/etc/rc\.d/init\.d/virtlogd -- gen_context(system_u:object_r:virtlogd_initrc_exec_t,s0) + +/usr/libexec/libvirt_lxc -- gen_context(system_u:object_r:virtd_lxc_exec_t,s0) + +/usr/sbin/libvirtd -- gen_context(system_u:object_r:virtd_exec_t,s0) +/usr/sbin/virtlockd -- gen_context(system_u:object_r:virtlogd_exec_t,s0) +/usr/sbin/virtlogd -- gen_context(system_u:object_r:virtlogd_exec_t,s0) +/usr/bin/virsh -- gen_context(system_u:object_r:virsh_exec_t,s0) + +/usr/sbin/virtinterfaced -- gen_context(system_u:object_r:virtinterfaced_exec_t,s0) +/usr/sbin/virtlxcd -- gen_context(system_u:object_r:virtd_lxc_exec_t,s0) +/usr/sbin/virtnetworkd -- gen_context(system_u:object_r:virtnetworkd_exec_t,s0) +/usr/sbin/virtnodedevd -- gen_context(system_u:object_r:virtnodedevd_exec_t,s0) +/usr/sbin/virtnwfilterd -- gen_context(system_u:object_r:virtnwfilterd_exec_t,s0) +/usr/sbin/virtproxyd -- gen_context(system_u:object_r:virtproxyd_exec_t,s0) +/usr/sbin/virtqemud -- gen_context(system_u:object_r:virtqemud_exec_t,s0) +/usr/sbin/virtsecretd -- gen_context(system_u:object_r:virtsecretd_exec_t,s0) +/usr/sbin/virtstoraged -- gen_context(system_u:object_r:virtstoraged_exec_t,s0) +/usr/sbin/virtvboxd -- gen_context(system_u:object_r:virtvboxd_exec_t,s0) +/usr/sbin/virtvzd -- gen_context(system_u:object_r:virtvzd_exec_t,s0) +/usr/sbin/virtxend -- gen_context(system_u:object_r:virtxend_exec_t,s0) + +/var/cache/libvirt(/.*)? gen_context(system_u:object_r:virt_cache_t,s0-mls_systemhigh) + +/var/lib/libvirt(/.*)? gen_context(system_u:object_r:virt_var_lib_t,s0) +/var/lib/libvirt/boot(/.*)? gen_context(system_u:object_r:virt_content_t,s0) +/var/lib/libvirt/images(/.*)? gen_context(system_u:object_r:virt_image_t,s0) +/var/lib/libvirt/isos(/.*)? gen_context(system_u:object_r:virt_content_t,s0) +/var/lib/libvirt/lockd(/.*)? gen_context(system_u:object_r:virt_var_lockd_t,s0) +/var/lib/libvirt/qemu(/.*)? gen_context(system_u:object_r:qemu_var_run_t,s0-mls_systemhigh) + +/var/log/log(/.*)? gen_context(system_u:object_r:virt_log_t,s0) +/var/log/libvirt(/.*)? gen_context(system_u:object_r:virt_log_t,s0) +/var/run/libvirtd\.pid -- gen_context(system_u:object_r:virt_var_run_t,s0) +# Avoid calling m4's "interface" by using en empty string +/var/run/libvirt/interfac(e)(/.*)? gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/libvirt/nodedev(/.*)? gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/libvirt/nwfilter(/.*)? gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/libvirt/secrets(/.*)? gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/libvirt/storage(/.*)? gen_context(system_u:object_r:virtstoraged_var_run_t,s0) + +/var/run/virtlogd\.pid -- gen_context(system_u:object_r:virtlogd_var_run_t,s0) +/var/run/virtlxcd\.pid -- gen_context(system_u:object_r:virt_lxc_var_run_t,s0) +/var/run/virtqemud\.pid -- gen_context(system_u:object_r:virtqemud_var_run_t,s0) +/var/run/virtvboxd\.pid -- gen_context(system_u:object_r:virtvboxd_var_run_t,s0) +/var/run/virtproxyd\.pid -- gen_context(system_u:object_r:virtproxyd_var_run_t,s0) +/var/run/virtinterfaced\.pid -- gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/virtnetworkd\.pid -- gen_context(system_u:object_r:virtnetworkd_var_run_t,s0) +/var/run/virtnodedevd\.pid -- gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/virtnwfilterd\.pid -- gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/virtnwfilterd-binding\.pid -- gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/virtsecretd\.pid -- gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/virtstoraged\.pid -- gen_context(system_u:object_r:virtstoraged_var_run_t,s0) + +/var/run/libvirt(/.*)? gen_context(system_u:object_r:virt_var_run_t,s0) +/var/run/libvirt/qemu(/.*)? gen_context(system_u:object_r:qemu_var_run_t,s0-mls_systemhigh) +/var/run/libvirt/lxc(/.*)? gen_context(system_u:object_r:virt_lxc_var_run_t,s0) +/var/run/libvirt/libvirt-sock -s gen_context(system_u:object_r:virt_var_run_t,s0) +/var/run/libvirt/virtlogd-sock -s gen_context(system_u:object_r:virtlogd_var_run_t,s0) +/var/run/libvirt/virtinterfaced-admin-sock -s gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/libvirt/virtinterfaced-sock -s gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/libvirt/virtinterfaced-sock-ro -s gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/libvirt/virtlxcd-admin-sock -s gen_context(system_u:object_r:virt_lxc_var_run_t,s0) +/var/run/libvirt/virtlxcd-sock -s gen_context(system_u:object_r:virt_lxc_var_run_t,s0) +/var/run/libvirt/virtlxcd-sock-ro -s gen_context(system_u:object_r:virt_lxc_var_run_t,s0) +/var/run/libvirt/virtnetworkd-admin-sock -s gen_context(system_u:object_r:virtnetworkd_var_run_t,s0) +/var/run/libvirt/virtnetworkd-sock -s gen_context(system_u:object_r:virtnetworkd_var_run_t,s0) +/var/run/libvirt/virtnetworkd-sock-ro -s gen_context(system_u:object_r:virtnetworkd_var_run_t,s0) +/var/run/libvirt/virtnodedevd-admin-sock -s gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/libvirt/virtnodedevd-sock -s gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/libvirt/virtnodedevd-sock-ro -s gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/libvirt/virtnwfilterd-admin-sock -s gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/libvirt/virtnwfilterd-sock -s gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/libvirt/virtnwfilterd-sock-ro -s gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/libvirt/virtproxyd-admin-sock -s gen_context(system_u:object_r:virtproxyd_var_run_t,s0) +/var/run/libvirt/virtproxyd-sock -s gen_context(system_u:object_r:virtproxyd_var_run_t,s0) +/var/run/libvirt/virtproxyd-sock-ro -s gen_context(system_u:object_r:virtproxyd_var_run_t,s0) +/var/run/libvirt/virtqemud-admin-sock -s gen_context(system_u:object_r:virtqemud_var_run_t,s0) +/var/run/libvirt/virtqemud-sock -s gen_context(system_u:object_r:virtqemud_var_run_t,s0) +/var/run/libvirt/virtqemud-sock-ro -s gen_context(system_u:object_r:virtqemud_var_run_t,s0) +/var/run/libvirt/virtsecretd-admin-sock -s gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/libvirt/virtsecretd-sock -s gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/libvirt/virtsecretd-sock-ro -s gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/libvirt/virtstoraged-admin-sock -s gen_context(system_u:object_r:virtstoraged_var_run_t,s0) +/var/run/libvirt/virtstoraged-sock -s gen_context(system_u:object_r:virtstoraged_var_run_t,s0) +/var/run/libvirt/virtstoraged-sock-ro -s gen_context(system_u:object_r:virtstoraged_var_run_t,s0) +/var/run/libvirt/virtvboxd-admin-sock -s gen_context(system_u:object_r:virtvboxd_var_run_t,s0) +/var/run/libvirt/virtvboxd-sock -s gen_context(system_u:object_r:virtvboxd_var_run_t,s0) +/var/run/libvirt/virtvboxd-sock-ro -s gen_context(system_u:object_r:virtvboxd_var_run_t,s0) + +/usr/lib/systemd/system/*virtlogd.* gen_context(system_u:object_r:virtlogd_unit_file_t,s0) + +/usr/lib/systemd/system/virt.*\.service -- gen_context(system_u:object_r:virtd_unit_file_t,s0) +/usr/lib/systemd/system/libvirt.*\.service -- gen_context(system_u:object_r:virtd_unit_file_t,s0) diff --git a/src/security/selinux/virt.if b/src/security/selinux/virt.if new file mode 100644 index 0000000000..7e92675750 --- /dev/null +++ b/src/security/selinux/virt.if @@ -0,0 +1,1984 @@ +## <summary>Libvirt virtualization API</summary> + +######################################## +## <summary> +## virtd_lxc_t stub interface. No access allowed. +## </summary> +## <param name="domain" unused="true"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_stub_lxc',` + gen_require(` + type virtd_lxc_t; + ') +') + +######################################## +## <summary> +## svirt_sandbox_domain attribute stub interface. No access allowed. +## </summary> +## <param name="domain" unused="true"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_stub_svirt_sandbox_domain',` + gen_require(` + attribute svirt_sandbox_domain; + ') +') + +######################################## +## <summary> +## container_file_t stub interface. No access allowed. +## </summary> +## <param name="domain" unused="true"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_stub_container_image',` + gen_require(` + type container_file_t; + ') +') + +interface(`virt_stub_svirt_sandbox_file',` + gen_require(` + type container_file_t; + type container_ro_file_t; + ') +') + +######################################## +## <summary> +## Creates types and rules for a basic +## qemu process domain. +## </summary> +## <param name="prefix"> +## <summary> +## Prefix for the domain. +## </summary> +## </param> +# +template(`virt_domain_template',` + gen_require(` + attribute virt_image_type, virt_domain; + attribute virt_tmpfs_type; + attribute virt_ptynode; + type qemu_exec_t; + type virtlogd_t; + ') + + type $1_t, virt_domain; + application_domain($1_t, qemu_exec_t) + domain_user_exemption_target($1_t) + mls_rangetrans_target($1_t) + mcs_constrained($1_t) + role system_r types $1_t; + + type $1_devpts_t, virt_ptynode; + term_pty($1_devpts_t) + + kernel_read_system_state($1_t) + + auth_read_passwd($1_t) + + logging_send_syslog_msg($1_t) + + allow $1_t $1_devpts_t:chr_file { rw_chr_file_perms setattr_chr_file_perms }; + term_create_pty($1_t, $1_devpts_t) + + # Allow domain to write to pipes connected to virtlogd + allow $1_t virtlogd_t:fd use; + allow $1_t virtlogd_t:fifo_file rw_inherited_fifo_file_perms; +') + +###################################### +## <summary> +## Creates types and rules for a basic +## virt driver domain. +## </summary> +## <param name="prefix"> +## <summary> +## Prefix for the domain. +## </summary> +## </param> +# +template(`virt_driver_template',` + gen_require(` + attribute virt_driver_domain; + attribute virt_driver_executable; + attribute virt_driver_var_run; + type virtd_t; + type virtqemud_t; + type virt_etc_t; + type virt_etc_rw_t; + type virt_var_run_t; + ') + + type $1_t, virt_driver_domain; + + type $1_exec_t, virt_driver_executable; + init_daemon_domain($1_t, $1_exec_t) + + type $1_var_run_t, virt_driver_var_run; + files_pid_file($1_var_run_t) + + ################################## + # + # Local policy + # + + allow $1_t self:netlink_audit_socket create; + allow $1_t self:netlink_kobject_uevent_socket create_socket_perms; + allow $1_t self:netlink_route_socket create_netlink_socket_perms; + allow $1_t self:rawip_socket create_socket_perms; + allow $1_t self:unix_dgram_socket create_socket_perms; + + allow virt_driver_domain virtd_t:unix_stream_socket rw_stream_socket_perms; + allow virt_driver_domain virtqemud_t:unix_stream_socket connectto; + + manage_dirs_pattern($1_t, virt_var_run_t, virt_var_run_t) + manage_dirs_pattern($1_t, $1_var_run_t, $1_var_run_t) + manage_files_pattern($1_t, $1_var_run_t, $1_var_run_t) + manage_sock_files_pattern($1_t, virt_var_run_t, $1_var_run_t) + files_pid_filetrans($1_t, $1_var_run_t, { dir file sock_file } ) + filetrans_pattern($1_t, virt_var_run_t, $1_var_run_t, { file sock_file } ) + + read_files_pattern($1_t, virt_etc_t, virt_etc_t) + manage_dirs_pattern($1_t, virt_etc_rw_t, virt_etc_rw_t) + manage_files_pattern($1_t, virt_etc_rw_t, virt_etc_rw_t) + filetrans_pattern($1_t, virt_etc_t, virt_etc_rw_t, dir) + + read_files_pattern(virt_driver_domain, virtqemud_t, virtqemud_t) + + kernel_dgram_send($1_t) + + auth_read_passwd($1_t) + + dbus_read_pid_files($1_t) + dbus_stream_connect_system_dbusd($1_t) + + dev_read_sysfs($1_t) + + files_read_non_security_files($1_t) + init_read_utmp($1_t) + + logging_send_syslog_msg($1_t) + + miscfiles_read_generic_certs($1_t) + + virt_manage_cache($1_t) + virt_manage_pid_files($1_t) + virt_stream_connect($1_t) + + optional_policy(` + dbus_system_bus_client($1_t) + ') + + optional_policy(` + dnsmasq_filetrans_named_content_fromdir($1_t, $1_var_run_t) + ') + + optional_policy(` + systemd_dbus_chat_logind($1_t) + systemd_machined_stream_connect($1_t) + systemd_write_inhibit_pipes($1_t) + ') +') + +######################################## +## <summary> +## Make the specified type usable as a virt image +## </summary> +## <param name="type"> +## <summary> +## Type to be used as a virtual image +## </summary> +## </param> +# +interface(`virt_image',` + gen_require(` + attribute virt_image_type; + ') + + typeattribute $1 virt_image_type; + files_type($1) + + # virt images can be assigned to blk devices + dev_node($1) +') + +####################################### +## <summary> +## Getattr on virt executable. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed to transition. +## </summary> +## </param> +# +interface(`virt_getattr_exec',` + gen_require(` + attribute virt_driver_executable; + type virtd_exec_t; + ') + + allow $1 virtd_exec_t:file getattr; + allow $1 virt_driver_executable:file getattr; +') + +######################################## +## <summary> +## Execute a domain transition to run virt. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed to transition. +## </summary> +## </param> +# +interface(`virt_domtrans',` + gen_require(` + type virtd_t, virtd_exec_t; + ') + + domtrans_pattern($1, virtd_exec_t, virtd_t) +') + +######################################## +## <summary> +## Execute virtd in the caller domain. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_exec',` + gen_require(` + attribute virt_driver_executable; + type virtd_exec_t; + ') + + can_exec($1, virtd_exec_t) + can_exec($1, virt_driver_executable) +') + +####################################### +## <summary> +## Connect to virt over a unix domain stream socket. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_stream_connect',` + gen_require(` + attribute virt_driver_domain; + attribute virt_driver_var_run; + type virtd_t, virt_var_run_t; + ') + + files_search_pids($1) + stream_connect_pattern($1, virt_var_run_t, virt_var_run_t, virtd_t) + stream_connect_pattern($1, virt_driver_var_run, virt_driver_var_run, virt_driver_domain) +') + +######################################## +## <summary> +## Read and write to virt_domain unix +## stream sockets. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_rw_stream_sockets_virt_domain',` + gen_require(` + attribute virt_domain; + ') + + allow $1 virt_domain:unix_stream_socket { read write }; +') + + +####################################### +## <summary> +## Connect to svirt process over a unix domain stream socket. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_stream_connect_svirt',` + gen_require(` + type svirt_t; + type svirt_image_t; + ') + + stream_connect_pattern($1, svirt_image_t, svirt_image_t, svirt_t) +') + +######################################## +## <summary> +## Read and write to apmd unix +## stream sockets. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_rw_stream_sockets_svirt',` + gen_require(` + type svirt_t; + ') + + allow $1 svirt_t:unix_stream_socket { getopt read setopt write }; +') + +######################################## +## <summary> +## Allow domain to attach to virt TUN devices +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_attach_tun_iface',` + gen_require(` + attribute virt_driver_domain; + type virtd_t; + ') + + allow $1 virtd_t:tun_socket relabelfrom; + allow $1 virt_driver_domain:tun_socket relabelfrom; + allow $1 self:tun_socket relabelto; +') + +######################################## +## <summary> +## Allow domain to attach to virt sandbox TUN devices +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_attach_sandbox_tun_iface',` + gen_require(` + attribute svirt_sandbox_domain; + ') + + allow $1 svirt_sandbox_domain:tun_socket relabelfrom; + allow $1 self:tun_socket relabelto; +') + +######################################## +## <summary> +## Read virt config files. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_read_config',` + gen_require(` + type virt_etc_t, virt_etc_rw_t; + ') + + files_search_etc($1) + read_files_pattern($1, virt_etc_t, virt_etc_t) + read_files_pattern($1, virt_etc_rw_t, virt_etc_rw_t) + read_lnk_files_pattern($1, virt_etc_rw_t, virt_etc_rw_t) +') + +######################################## +## <summary> +## manage virt config files. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_manage_config',` + gen_require(` + type virt_etc_t, virt_etc_rw_t; + ') + + files_search_etc($1) + manage_files_pattern($1, virt_etc_t, virt_etc_t) + manage_files_pattern($1, virt_etc_rw_t, virt_etc_rw_t) + manage_lnk_files_pattern($1, virt_etc_rw_t, virt_etc_rw_t) +') + +######################################## +## <summary> +## Allow domain to manage virt image files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_getattr_content',` + gen_require(` + type virt_content_t; + ') + + allow $1 virt_content_t:file getattr_file_perms; +') + +######################################## +## <summary> +## Allow domain to manage virt image files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_read_content',` + gen_require(` + type virt_content_t; + ') + + virt_search_lib($1) + allow $1 virt_content_t:dir list_dir_perms; + allow $1 virt_content_t:blk_file map; + allow $1 virt_content_t:file map; + list_dirs_pattern($1, virt_content_t, virt_content_t) + read_files_pattern($1, virt_content_t, virt_content_t) + read_lnk_files_pattern($1, virt_content_t, virt_content_t) + read_blk_files_pattern($1, virt_content_t, virt_content_t) + read_chr_files_pattern($1, virt_content_t, virt_content_t) + + tunable_policy(`virt_use_nfs',` + fs_list_nfs($1) + fs_read_nfs_files($1) + fs_read_nfs_symlinks($1) + ') + + tunable_policy(`virt_use_samba',` + fs_list_cifs($1) + fs_read_cifs_files($1) + fs_read_cifs_symlinks($1) + ') +') + +######################################## +## <summary> +## Allow domain to write virt image files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_write_content',` + gen_require(` + type virt_content_t; + ') + + allow $1 virt_content_t:file write_file_perms; +') + +######################################## +## <summary> +## Read virt PID symlinks files. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_read_pid_symlinks',` + gen_require(` + attribute virt_driver_var_run; + type virt_var_run_t; + ') + + files_search_pids($1) + read_lnk_files_pattern($1, virt_var_run_t, virt_var_run_t) + read_lnk_files_pattern($1, virt_driver_var_run, virt_driver_var_run) +') + +######################################## +## <summary> +## Read virt PID files. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_read_pid_files',` + gen_require(` + attribute virt_driver_var_run; + type virt_var_run_t; + ') + + files_search_pids($1) + read_files_pattern($1, virt_var_run_t, virt_var_run_t) + read_lnk_files_pattern($1, virt_var_run_t, virt_var_run_t) + read_files_pattern($1, virt_driver_var_run, virt_driver_var_run) + read_lnk_files_pattern($1, virt_driver_var_run, virt_driver_var_run) +') + +######################################## +## <summary> +## Manage virt pid directories. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_manage_pid_dirs',` + gen_require(` + attribute virt_driver_var_run; + type virt_var_run_t; + type virt_lxc_var_run_t; + ') + + files_search_pids($1) + manage_dirs_pattern($1, virt_var_run_t, virt_var_run_t) + manage_dirs_pattern($1, virt_driver_var_run, virt_driver_var_run) + manage_dirs_pattern($1, virt_lxc_var_run_t, virt_lxc_var_run_t) + virt_filetrans_named_content($1) +') + +######################################## +## <summary> +## Manage virt pid files. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_manage_pid_files',` + gen_require(` + attribute virt_driver_var_run; + type virt_var_run_t; + type virt_lxc_var_run_t; + ') + + files_search_pids($1) + manage_files_pattern($1, virt_var_run_t, virt_var_run_t) + manage_files_pattern($1, virt_driver_var_run, virt_driver_var_run) + manage_files_pattern($1, virt_lxc_var_run_t, virt_lxc_var_run_t) +') + +######################################## +## <summary> +## Create objects in the pid directory +## with a private type with a type transition. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +## <param name="file"> +## <summary> +## Type to which the created node will be transitioned. +## </summary> +## </param> +## <param name="class"> +## <summary> +## Object class(es) (single or set including {}) for which this +## the transition will occur. +## </summary> +## </param> +## <param name="name" optional="true"> +## <summary> +## The name of the object being created. +## </summary> +## </param> +# +interface(`virt_pid_filetrans',` + gen_require(` + attribute virt_driver_var_run; + type virt_var_run_t; + ') + + filetrans_pattern($1, virt_var_run_t, $2, $3, $4) + filetrans_pattern($1, virt_driver_var_run, $2, $3, $4) +') + +######################################## +## <summary> +## Search virt lib directories. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_search_lib',` + gen_require(` + type virt_var_lib_t; + ') + + allow $1 virt_var_lib_t:dir search_dir_perms; + files_search_var_lib($1) +') + +######################################## +## <summary> +## Read virt lib files. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_read_lib_files',` + gen_require(` + type virt_var_lib_t; + ') + + files_search_var_lib($1) + read_files_pattern($1, virt_var_lib_t, virt_var_lib_t) + list_dirs_pattern($1, virt_var_lib_t, virt_var_lib_t) + read_lnk_files_pattern($1, virt_var_lib_t, virt_var_lib_t) +') + +######################################## +## <summary> +## Dontaudit inherited read virt lib files. +## </summary> +## <param name="domain"> +## <summary> +## Domain to not audit. +## </summary> +## </param> +# +interface(`virt_dontaudit_read_lib_files',` + gen_require(` + type virt_var_lib_t; + ') + + dontaudit $1 virt_var_lib_t:file read_inherited_file_perms; +') + +######################################## +## <summary> +## Create, read, write, and delete +## virt lib files. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_manage_lib_files',` + gen_require(` + type virt_var_lib_t; + ') + + files_search_var_lib($1) + manage_files_pattern($1, virt_var_lib_t, virt_var_lib_t) +') + +######################################## +## <summary> +## Allow the specified domain to read virt's log files. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +## <rolecap/> +# +interface(`virt_read_log',` + gen_require(` + type virt_log_t; + ') + + logging_search_logs($1) + read_files_pattern($1, virt_log_t, virt_log_t) +') + +######################################## +## <summary> +## Allow the specified domain to append +## virt log files. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_append_log',` + gen_require(` + type virt_log_t; + ') + + logging_search_logs($1) + append_files_pattern($1, virt_log_t, virt_log_t) +') + +######################################## +## <summary> +## Allow domain to manage virt log files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_manage_log',` + gen_require(` + type virt_log_t; + ') + + manage_dirs_pattern($1, virt_log_t, virt_log_t) + manage_files_pattern($1, virt_log_t, virt_log_t) + manage_lnk_files_pattern($1, virt_log_t, virt_log_t) +') + +######################################## +## <summary> +## Allow domain to getattr virt image direcories +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_getattr_images',` + gen_require(` + attribute virt_image_type; + ') + + virt_search_lib($1) + allow $1 virt_image_type:file getattr_file_perms; +') + +######################################## +## <summary> +## Allow domain to search virt image direcories +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_search_images',` + gen_require(` + attribute virt_image_type; + ') + + virt_search_lib($1) + allow $1 virt_image_type:dir search_dir_perms; +') + +######################################## +## <summary> +## Allow domain to read virt image files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_read_images',` + gen_require(` + type virt_var_lib_t; + attribute virt_image_type; + ') + + virt_search_lib($1) + allow $1 virt_image_type:dir list_dir_perms; + list_dirs_pattern($1, virt_image_type, virt_image_type) + read_files_pattern($1, virt_image_type, virt_image_type) + read_lnk_files_pattern($1, virt_image_type, virt_image_type) + read_blk_files_pattern($1, virt_image_type, virt_image_type) + read_chr_files_pattern($1, virt_image_type, virt_image_type) + + tunable_policy(`virt_use_nfs',` + fs_list_nfs($1) + fs_read_nfs_files($1) + fs_read_nfs_symlinks($1) + ') + + tunable_policy(`virt_use_samba',` + fs_list_cifs($1) + fs_read_cifs_files($1) + fs_read_cifs_symlinks($1) + ') +') + +######################################## +## <summary> +## Allow domain to read virt blk image files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_read_blk_images',` + gen_require(` + attribute virt_image_type; + ') + + read_blk_files_pattern($1, virt_image_type, virt_image_type) +') + +######################################## +## <summary> +## Allow domain to read/write virt image chr files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_rw_chr_files',` + gen_require(` + attribute virt_image_type; + ') + + rw_chr_files_pattern($1, virt_image_type, virt_image_type) +') + +######################################## +## <summary> +## Create, read, write, and delete +## svirt cache files. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_manage_cache',` + gen_require(` + type virt_cache_t; + ') + + files_search_var($1) + manage_dirs_pattern($1, virt_cache_t, virt_cache_t) + manage_files_pattern($1, virt_cache_t, virt_cache_t) + manage_lnk_files_pattern($1, virt_cache_t, virt_cache_t) +') + +######################################## +## <summary> +## Allow domain to manage virt image files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_manage_images',` + gen_require(` + type virt_var_lib_t; + attribute virt_image_type; + ') + + virt_search_lib($1) + allow $1 virt_image_type:dir list_dir_perms; + manage_dirs_pattern($1, virt_image_type, virt_image_type) + manage_files_pattern($1, virt_image_type, virt_image_type) + read_lnk_files_pattern($1, virt_image_type, virt_image_type) + rw_blk_files_pattern($1, virt_image_type, virt_image_type) + rw_chr_files_pattern($1, virt_image_type, virt_image_type) +') + +####################################### +## <summary> +## Allow domain to manage virt image files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_manage_default_image_type',` + gen_require(` + type virt_var_lib_t; + type virt_image_t; + ') + + virt_search_lib($1) + manage_dirs_pattern($1, virt_image_t, virt_image_t) + manage_files_pattern($1, virt_image_t, virt_image_t) + read_lnk_files_pattern($1, virt_image_t, virt_image_t) +') + +####################################### +## <summary> +## Get virtd services status +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed to transition. +## </summary> +## </param> +# +interface(`virtd_service_status',` + gen_require(` + type virtd_unit_file_t; + ') + + allow $1 virtd_unit_file_t:service status; +') + +######################################## +## <summary> +## Execute virt server in the virt domain. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed to transition. +## </summary> +## </param> +# +interface(`virt_systemctl',` + gen_require(` + type virtd_unit_file_t; + type virtd_t; + ') + + systemd_exec_systemctl($1) + init_reload_services($1) + allow $1 virtd_unit_file_t:file read_file_perms; + allow $1 virtd_unit_file_t:service manage_service_perms; + + ps_process_pattern($1, virtd_t) +') + +######################################## +## <summary> +## Ptrace the svirt domain +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed to transition. +## </summary> +## </param> +# +interface(`virt_ptrace',` + gen_require(` + attribute virt_domain; + ') + + allow $1 virt_domain:process ptrace; +') + +####################################### +## <summary> +## Execute Sandbox Files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_exec_sandbox_files',` + gen_require(` + attribute svirt_file_type; + ') + + can_exec($1, svirt_file_type) +') + +######################################## +## <summary> +## Allow any svirt_file_type to be an entrypoint of this domain +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +## <rolecap/> +# +interface(`virt_sandbox_entrypoint',` + gen_require(` + attribute svirt_file_type; + ') + allow $1 svirt_file_type:file entrypoint; +') + +####################################### +## <summary> +## List Sandbox Dirs +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_list_sandbox_dirs',` + gen_require(` + type svirt_sandbox_file_t; + ') + + list_dirs_pattern($1, svirt_sandbox_file_t, svirt_sandbox_file_t) +') + +####################################### +## <summary> +## Read Sandbox Files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_read_sandbox_files',` + gen_require(` + attribute svirt_file_type; + ') + + list_dirs_pattern($1, svirt_file_type, svirt_file_type) + read_files_pattern($1, svirt_file_type, svirt_file_type) + read_lnk_files_pattern($1, svirt_file_type, svirt_file_type) +') + +####################################### +## <summary> +## Manage Sandbox Files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_manage_sandbox_files',` + gen_require(` + attribute svirt_file_type; + ') + + manage_dirs_pattern($1, svirt_file_type, svirt_file_type) + manage_files_pattern($1, svirt_file_type, svirt_file_type) + manage_fifo_files_pattern($1, svirt_file_type, svirt_file_type) + manage_chr_files_pattern($1, svirt_file_type, svirt_file_type) + manage_lnk_files_pattern($1, svirt_file_type, svirt_file_type) + allow $1 svirt_file_type:dir_file_class_set { relabelfrom relabelto }; +') + +####################################### +## <summary> +## Getattr Sandbox File systems +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_getattr_sandbox_filesystem',` + gen_require(` + attribute svirt_file_type; + ') + + allow $1 svirt_file_type:filesystem getattr; +') + +####################################### +## <summary> +## Relabel Sandbox File systems +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_relabel_sandbox_filesystem',` + gen_require(` + attribute svirt_file_type; + ') + + allow $1 svirt_file_type:filesystem { relabelfrom relabelto }; +') + +####################################### +## <summary> +## Mounton Sandbox Files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_mounton_sandbox_file',` + gen_require(` + attribute svirt_file_type; + ') + + allow $1 svirt_file_type:dir_file_class_set mounton; +') + +####################################### +## <summary> +## Connect to virt over a unix domain stream socket. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_stream_connect_sandbox',` + gen_require(` + attribute svirt_sandbox_domain; + attribute svirt_file_type; + ') + + files_search_pids($1) + stream_connect_pattern($1, svirt_file_type, svirt_file_type, svirt_sandbox_domain) + ps_process_pattern(svirt_sandbox_domain, $1) +') + +######################################## +## <summary> +## Execute qemu in the svirt domain, and +## allow the specified role the svirt domain. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access +## </summary> +## </param> +## <param name="role"> +## <summary> +## The role to be allowed the sandbox domain. +## </summary> +## </param> +## <rolecap/> +# +interface(`virt_transition_svirt',` + gen_require(` + attribute virt_domain; + type virt_bridgehelper_t; + type svirt_image_t; + type svirt_socket_t; + ') + + allow $1 virt_domain:process transition; + role $2 types virt_domain; + role $2 types virt_bridgehelper_t; + role $2 types svirt_socket_t; + + allow $1 virt_domain:process { sigkill signal signull sigstop }; + allow $1 svirt_image_t:file { relabelfrom relabelto }; + allow $1 svirt_image_t:fifo_file { read_fifo_file_perms relabelto }; + allow $1 svirt_image_t:sock_file { create_sock_file_perms relabelto }; + allow $1 svirt_socket_t:unix_stream_socket create_stream_socket_perms; + + optional_policy(` + ptchown_run(virt_domain, $2) + ') +') + +######################################## +## <summary> +## Do not audit attempts to write virt daemon unnamed pipes. +## </summary> +## <param name="domain"> +## <summary> +## Domain to not audit. +## </summary> +## </param> +# +interface(`virt_dontaudit_write_pipes',` + gen_require(` + type virtd_t; + ') + + dontaudit $1 virtd_t:fd use; + dontaudit $1 virtd_t:fifo_file write_fifo_file_perms; +') + +######################################## +## <summary> +## Send a sigkill to virtual machines +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_kill_svirt',` + gen_require(` + attribute virt_domain; + ') + + allow $1 virt_domain:process sigkill; +') + +######################################## +## <summary> +## Send a sigkill to virtd daemon. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_kill',` + gen_require(` + attribute virt_driver_domain; + type virtd_t; + ') + + allow $1 virtd_t:process sigkill; + allow $1 virt_driver_domain:process sigkill; +') + +######################################## +## <summary> +## Send a signal to virtd daemon. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_signal',` + gen_require(` + attribute virt_driver_domain; + type virtd_t; + ') + + allow $1 virtd_t:process signal; + allow $1 virt_driver_domain:process signal; +') + +######################################## +## <summary> +## Send null signal to virtd daemon. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_signull',` + gen_require(` + attribute virt_driver_domain; + type virtd_t; + ') + + allow $1 virtd_t:process signull; + allow $1 virt_driver_domain:process signull; +') + +######################################## +## <summary> +## Send a signal to virtual machines +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_signal_svirt',` + gen_require(` + attribute virt_domain; + ') + + allow $1 virt_domain:process signal; +') + +######################################## +## <summary> +## Send a signal to sandbox domains +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_signal_sandbox',` + gen_require(` + attribute svirt_sandbox_domain; + ') + + allow $1 svirt_sandbox_domain:process signal; +') + +######################################## +## <summary> +## Manage virt home files. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_manage_home_files',` + gen_require(` + type virt_home_t; + ') + + userdom_search_user_home_dirs($1) + manage_files_pattern($1, virt_home_t, virt_home_t) +') + +######################################## +## <summary> +## allow domain to read +## virt tmpfs files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access +## </summary> +## </param> +# +interface(`virt_read_tmpfs_files',` + gen_require(` + attribute virt_tmpfs_type; + ') + + allow $1 virt_tmpfs_type:file read_file_perms; +') + +######################################## +## <summary> +## allow domain to manage +## virt tmpfs files +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access +## </summary> +## </param> +# +interface(`virt_manage_tmpfs_files',` + gen_require(` + attribute virt_tmpfs_type; + ') + + allow $1 virt_tmpfs_type:file manage_file_perms; +') + +######################################## +## <summary> +## Create .virt directory in the user home directory +## with an correct label. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_filetrans_home_content',` + gen_require(` + type virt_home_t; + type svirt_home_t; + ') + + userdom_user_home_dir_filetrans($1, virt_home_t, dir, ".libvirt") + userdom_user_home_dir_filetrans($1, virt_home_t, dir, ".virtinst") + filetrans_pattern($1, virt_home_t, svirt_home_t, dir, "qemu") + + optional_policy(` + gnome_config_filetrans($1, virt_home_t, dir, "libvirt") + gnome_cache_filetrans($1, virt_home_t, dir, "libvirt") + gnome_cache_filetrans($1, virt_home_t, dir, "libvirt-sandbox") + gnome_cache_filetrans($1, virt_home_t, dir, "gnome-boxes") + gnome_data_filetrans($1, svirt_home_t, dir, "images") + gnome_data_filetrans($1, svirt_home_t, dir, "boot") + ') +') + +######################################## +## <summary> +## Dontaudit attempts to Read virt_image_type devices. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_dontaudit_read_chr_dev',` + gen_require(` + attribute virt_image_type; + ') + + dontaudit $1 virt_image_type:chr_file read_chr_file_perms; +') + +######################################## +## <summary> +## Make the specified type usable as a virt file type +## </summary> +## <param name="type"> +## <summary> +## Type to be used as a virt file type +## </summary> +## </param> +# +interface(`virt_file_types',` + gen_require(` + attribute virt_file_type; + ') + + typeattribute $1 virt_file_type; +') + +######################################## +## <summary> +## Make the specified type usable as a svirt file type +## </summary> +## <param name="type"> +## <summary> +## Type to be used as a svirt file type +## </summary> +## </param> +# +interface(`svirt_file_types',` + gen_require(` + attribute svirt_file_type; + ') + + typeattribute $1 svirt_file_type; +') + + +######################################## +## <summary> +## Creates types and rules for a basic +## virt_lxc process domain. +## </summary> +## <param name="prefix"> +## <summary> +## Prefix for the domain. +## </summary> +## </param> +# +template(`virt_sandbox_domain_template',` + gen_require(` + attribute svirt_sandbox_domain; + ') + + type $1_t, svirt_sandbox_domain; + domain_type($1_t) + domain_user_exemption_target($1_t) + mls_rangetrans_target($1_t) + mcs_constrained($1_t) + role system_r types $1_t; + + logging_send_syslog_msg($1_t) + + kernel_read_system_state($1_t) + kernel_read_all_proc($1_t) + + # optional_policy(` + # container_runtime_typebounds($1_t) + # ') +') + +######################################## +## <summary> +## Make the specified type usable as a lxc domain +## </summary> +## <param name="type"> +## <summary> +## Type to be used as a lxc domain +## </summary> +## </param> +# +template(`virt_sandbox_domain',` + gen_require(` + attribute svirt_sandbox_domain; + ') + + typeattribute $1 svirt_sandbox_domain; +') + +######################################## +## <summary> +## Make the specified type usable as a lxc network domain +## </summary> +## <param name="type"> +## <summary> +## Type to be used as a lxc network domain +## </summary> +## </param> +# +template(`virt_sandbox_net_domain',` + gen_require(` + attribute sandbox_net_domain; + ') + + virt_sandbox_domain($1) + typeattribute $1 sandbox_net_domain; +') + +######################################## +## <summary> +## Make the specified type usable as a virt system domain +## </summary> +## <param name="type"> +## <summary> +## Type to be used as a virt system domain +## </summary> +## </param> +# +interface(`virt_system_domain_type',` + gen_require(` + attribute virt_system_domain; + ') + + typeattribute $1 virt_system_domain; +') + +######################################## +## <summary> +## Execute a qemu_exec_t in the callers domain +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_exec_qemu',` + gen_require(` + type qemu_exec_t; + ') + + can_exec($1, qemu_exec_t) +') + +######################################## +## <summary> +## Transition to virt named content +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_filetrans_named_content',` + gen_require(` + type virt_lxc_var_run_t; + type virt_var_run_t; + ') + + files_pid_filetrans($1, virt_lxc_var_run_t, dir, "libvirt-sandbox") + files_pid_filetrans($1, virt_var_run_t, dir, "libvirt") + files_pid_filetrans($1, virt_var_run_t, dir, "libguestfs") +') + +######################################## +## <summary> +## Execute qemu in the svirt domain, and +## allow the specified role the svirt domain. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access +## </summary> +## </param> +## <param name="role"> +## <summary> +## The role to be allowed the sandbox domain. +## </summary> +## </param> +## <rolecap/> +# +interface(`virt_transition_svirt_sandbox',` + gen_require(` + attribute svirt_sandbox_domain; + ') + + allow $1 svirt_sandbox_domain:process { signal_perms transition }; + role $2 types svirt_sandbox_domain; + allow $1 svirt_sandbox_domain:unix_dgram_socket sendto; + + allow svirt_sandbox_domain $1:fd use; + + allow svirt_sandbox_domain $1:process sigchld; + ps_process_pattern($1, svirt_sandbox_domain) +') + +######################################## +## <summary> +## Read the process state of virt sandbox containers +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_sandbox_read_state',` + gen_require(` + attribute svirt_sandbox_domain; + ') + + ps_process_pattern($1, svirt_sandbox_domain) +') + +######################################## +## <summary> +## Read and write to svirt_image devices. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_rw_svirt_dev',` + gen_require(` + type svirt_image_t; + ') + + allow $1 svirt_image_t:chr_file rw_file_perms; +') + +######################################## +## <summary> +## Read and write to svirt_image files. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_rw_svirt_image',` + gen_require(` + type svirt_image_t; + ') + + allow $1 svirt_image_t:file rw_file_perms; +') + +######################################## +## <summary> +## Read and write to svirt_image devices. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_rlimitinh',` + gen_require(` + type virtd_t; + ') + + allow $1 virtd_t:process { rlimitinh }; +') + +######################################## +## <summary> +## Read and write to svirt_image devices. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_noatsecure',` + gen_require(` + type virtd_t; + ') + + allow $1 virtd_t:process { noatsecure rlimitinh }; +') + +######################################## +## <summary> +## All of the rules required to administrate +## an virt environment +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +## <param name="role"> +## <summary> +## Role allowed access. +## </summary> +## </param> +## <rolecap/> +# +interface(`virt_admin',` + gen_require(` + attribute virt_domain; + attribute virt_system_domain; + attribute svirt_file_type; + attribute virt_file_type; + type virtd_initrc_exec_t; + type virtd_unit_file_t; + ') + + allow $1 virt_system_domain:process signal_perms; + allow $1 virt_domain:process signal_perms; + ps_process_pattern($1, virt_system_domain) + ps_process_pattern($1, virt_domain) + tunable_policy(`deny_ptrace',`',` + allow $1 virt_system_domain:process ptrace; + allow $1 virt_domain:process ptrace; + ') + + init_labeled_script_domtrans($1, virtd_initrc_exec_t) + domain_system_change_exemption($1) + role_transition $2 virtd_initrc_exec_t system_r; + allow $2 system_r; + + allow $1 virt_domain:process signal_perms; + + admin_pattern($1, virt_file_type) + admin_pattern($1, svirt_file_type) + + virt_systemctl($1) + allow $1 virtd_unit_file_t:service all_service_perms; + + virt_stream_connect_sandbox($1) + virt_stream_connect_svirt($1) + virt_stream_connect($1) +') + +####################################### +## <summary> +## Getattr on virt executable. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed to transition. +## </summary> +## </param> +# +interface(`virt_default_capabilities',` + gen_require(` + attribute sandbox_caps_domain; + ') + + typeattribute $1 sandbox_caps_domain; +') + +######################################## +## <summary> +## Send and receive messages from +## virt over dbus. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_dbus_chat',` + gen_require(` + attribute virt_driver_domain; + type virtd_t; + class dbus send_msg; + ') + + allow $1 virtd_t:dbus send_msg; + allow virtd_t $1:dbus send_msg; + allow $1 virt_driver_domain:dbus send_msg; + allow virt_driver_domain $1:dbus send_msg; + ps_process_pattern(virtd_t, $1) + ps_process_pattern(virt_driver_domain, $1) +') + +######################################## +## <summary> +## Execute a file in a sandbox directory +## in the specified domain. +## </summary> +## <desc> +## <p> +## Execute a file in a sandbox directory +## in the specified domain. This allows +## the specified domain to execute any file +## on these filesystems in the specified +## domain. +## </p> +## </desc> +## <param name="domain"> +## <summary> +## Domain allowed to transition. +## </summary> +## </param> +## <param name="target_domain"> +## <summary> +## The type of the new process. +## </summary> +## </param> +# +interface(`virt_sandbox_domtrans',` + gen_require(` + type container_file_t; + ') + + domtrans_pattern($1,container_file_t, $2) +') + +######################################## +## <summary> +## Dontaudit read the process state (/proc/pid) of libvirt +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_dontaudit_read_state',` + gen_require(` + type virtd_t; + ') + + dontaudit $1 virtd_t:dir search_dir_perms; + dontaudit $1 virtd_t:file read_file_perms; + dontaudit $1 virtd_t:lnk_file read_lnk_file_perms; +') + +####################################### +## <summary> +## Send to libvirt with a unix dgram socket. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_dgram_send',` + gen_require(` + type virtd_t, virt_var_run_t; + ') + + files_search_pids($1) + dgram_send_pattern($1, virt_var_run_t, virt_var_run_t, virtd_t) +') + +######################################## +## <summary> +## Manage svirt home files,dirs and sockfiles. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_svirt_manage_home',` + gen_require(` + type svirt_home_t; + ') + + manage_files_pattern($1, svirt_home_t, svirt_home_t) + manage_dirs_pattern($1, svirt_home_t, svirt_home_t) + manage_sock_files_pattern($1, svirt_home_t, svirt_home_t) +') + +######################################## +## <summary> +## Manage svirt tmp files,dirs and sockfiles. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_svirt_manage_tmp',` + gen_require(` + type svirt_tmp_t; + ') + + manage_files_pattern($1, svirt_tmp_t, svirt_tmp_t) + manage_dirs_pattern($1, svirt_tmp_t, svirt_tmp_t) + manage_sock_files_pattern($1, svirt_tmp_t, svirt_tmp_t) +') + +######################################## +## <summary> +## Read qemu PID files. +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +interface(`virt_read_qemu_pid_files',` + gen_require(` + type qemu_var_run_t; + ') + + files_search_pids($1) + list_dirs_pattern($1, qemu_var_run_t, qemu_var_run_t) + read_files_pattern($1, qemu_var_run_t, qemu_var_run_t) +') diff --git a/src/security/selinux/virt.te b/src/security/selinux/virt.te new file mode 100644 index 0000000000..953778a6e4 --- /dev/null +++ b/src/security/selinux/virt.te @@ -0,0 +1,2078 @@ +policy_module(virt, 1.5.0) + +######################################## +# +# Declarations +# + +## <desc> +## <p> +## Allow confined virtual guests to use serial/parallel communication ports +## </p> +## </desc> +gen_tunable(virt_use_comm, false) + +## <desc> +## <p> +## Allow virtual processes to run as userdomains +## </p> +## </desc> +gen_tunable(virt_transition_userdomain, false) + +## <desc> +## <p> +## Allow confined virtual guests to use executable memory and executable stack +## </p> +## </desc> +gen_tunable(virt_use_execmem, false) + +## <desc> +## <p> +## Allow virtqemu driver to use executable memory and executable stack +## </p> +## </desc> +gen_tunable(virtqemud_use_execmem, true) + +## <desc> +## <p> +## Allow confined virtual guests to read fuse files +## </p> +## </desc> +gen_tunable(virt_use_fusefs, false) + +## <desc> +## <p> +## Allow confined virtual guests to use glusterd +## </p> +## </desc> +gen_tunable(virt_use_glusterd, false) + +## <desc> +## <p> +## Allow sandbox containers to share apache content +## </p> +## </desc> +gen_tunable(virt_sandbox_share_apache_content, false) + +## <desc> +## <p> +## Allow sandbox containers manage fuse files +## </p> +## </desc> +gen_tunable(virt_sandbox_use_fusefs, false) + +## <desc> +## <p> +## Allow confined virtual guests to manage nfs files +## </p> +## </desc> +gen_tunable(virt_use_nfs, false) + +## <desc> +## <p> +## Allow confined virtual guests to manage cifs files +## </p> +## </desc> +gen_tunable(virt_use_samba, false) + +## <desc> +## <p> +## Allow confined virtual guests to interact with the sanlock +## </p> +## </desc> +gen_tunable(virt_use_sanlock, false) + +## <desc> +## <p> +## Allow confined virtual guests to interact with rawip sockets +## </p> +## </desc> +gen_tunable(virt_use_rawip, false) + +## <desc> +## <p> +## Allow confined virtual guests to interact with the xserver +## </p> +## </desc> +gen_tunable(virt_use_xserver, false) + +## <desc> +## <p> +## Allow confined virtual guests to use usb devices +## </p> +## </desc> +gen_tunable(virt_use_usb, true) + +## <desc> +## <p> +## Allow confined virtual guests to use smartcards +## </p> +## </desc> +gen_tunable(virt_use_pcscd, false) + +## <desc> +## <p> +## Allow sandbox containers to send audit messages + +## </p> +## </desc> +gen_tunable(virt_sandbox_use_audit, true) + +## <desc> +## <p> +## Allow sandbox containers to use netlink system calls +## </p> +## </desc> +gen_tunable(virt_sandbox_use_netlink, false) + +## <desc> +## <p> +## Allow sandbox containers to use sys_admin system calls, for example mount +## </p> +## </desc> +gen_tunable(virt_sandbox_use_sys_admin, false) + +## <desc> +## <p> +## Allow sandbox containers to use mknod system calls +## </p> +## </desc> +gen_tunable(virt_sandbox_use_mknod, false) + +## <desc> +## <p> +## Allow sandbox containers to use all capabilities +## </p> +## </desc> +gen_tunable(virt_sandbox_use_all_caps, true) + +## <desc> +## <p> +## Allow virtlockd read and lock block devices. +## </p> +## </desc> +gen_tunable(virt_lockd_blk_devs, false) + +gen_require(` + class passwd rootok; + class passwd passwd; +') + +attribute virsh_transition_domain; +attribute virt_ptynode; +attribute virt_system_domain; +attribute virt_domain; +attribute virt_driver_domain; +attribute virt_driver_executable; +attribute virt_driver_var_run; +attribute virt_image_type; +attribute virt_tmpfs_type; +attribute svirt_file_type; +attribute virt_file_type; +attribute sandbox_net_domain; +attribute sandbox_caps_domain; + +type svirt_tmp_t, svirt_file_type; +files_tmp_file(svirt_tmp_t) + +type svirt_tmpfs_t, virt_tmpfs_type, svirt_file_type; +files_tmpfs_file(svirt_tmpfs_t) + +type svirt_image_t, virt_image_type, svirt_file_type; +files_type(svirt_image_t) +dev_node(svirt_image_t) +dev_associate_sysfs(svirt_image_t) + +virt_domain_template(svirt) +role system_r types svirt_t; +typealias svirt_t alias qemu_t; + +virt_domain_template(svirt_tcg) +role system_r types svirt_tcg_t; + +type qemu_exec_t, virt_file_type; + +type virt_cache_t alias svirt_cache_t, virt_file_type; +files_type(virt_cache_t) + +type virt_etc_t, virt_file_type; +files_config_file(virt_etc_t) + +type virt_etc_rw_t, virt_file_type; +files_type(virt_etc_rw_t) + +type virt_home_t, virt_file_type; +userdom_user_home_content(virt_home_t) + +type svirt_home_t, svirt_file_type; +userdom_user_home_content(svirt_home_t) + +# virt Image files +type virt_image_t, virt_file_type; # customizable +virt_image(virt_image_t) +files_mountpoint(virt_image_t) + +# virt Image files +type virt_content_t, virt_file_type; # customizable +virt_image(virt_content_t) +userdom_user_home_content(virt_content_t) + +type virt_tmp_t, virt_file_type; +files_tmp_file(virt_tmp_t) + +type virt_log_t, virt_file_type; +logging_log_file(virt_log_t) +mls_trusted_object(virt_log_t) + +type virt_lock_t, virt_file_type; +files_lock_file(virt_lock_t) + +type virt_var_run_t, virt_file_type; +files_pid_file(virt_var_run_t) + +type virt_var_lib_t, virt_file_type; +files_mountpoint(virt_var_lib_t) + +type virt_var_lockd_t, virt_file_type; +files_type(virt_var_lockd_t) + +type virtd_t, virt_system_domain; +type virtd_exec_t, virt_file_type; +init_daemon_domain(virtd_t, virtd_exec_t) +domain_obj_id_change_exemption(virtd_t) +domain_subj_id_change_exemption(virtd_t) + +type virtd_unit_file_t, virt_file_type; +systemd_unit_file(virtd_unit_file_t) + +type virtd_initrc_exec_t, virt_file_type; +init_script_file(virtd_initrc_exec_t) + +type virtd_keytab_t; +files_type(virtd_keytab_t) + +type virtlogd_t, virt_system_domain; +type virtlogd_exec_t, virt_file_type; +init_daemon_domain(virtlogd_t, virtlogd_exec_t) + +type virtlogd_etc_t, virt_file_type; +files_config_file(virtlogd_etc_t) + +type virtlogd_var_run_t, virt_file_type; +files_pid_file(virtlogd_var_run_t) + +type virtlogd_unit_file_t, virt_file_type; +systemd_unit_file(virtlogd_unit_file_t) + +type virtlogd_initrc_exec_t, virt_file_type; +init_script_file(virtlogd_initrc_exec_t) + +type qemu_var_run_t, virt_file_type; +typealias qemu_var_run_t alias svirt_var_run_t; +files_pid_file(qemu_var_run_t) +mls_trusted_object(qemu_var_run_t) + +ifdef(`enable_mcs',` + init_ranged_daemon_domain(virtd_t, virtd_exec_t, s0 - mcs_systemhigh) + init_ranged_daemon_domain(virtlogd_t, virtlogd_exec_t, s0 - mcs_systemhigh) +') + +ifdef(`enable_mls',` + init_ranged_daemon_domain(virtd_t, virtd_exec_t, s0 - mls_systemhigh) + init_ranged_daemon_domain(virtlogd_t, virtlogd_exec_t, s0 - mls_systemhigh) +') + +# virtinterfaced +virt_driver_template(virtinterfaced) +files_type(virtinterfaced_t) + +# virtnetworkd +virt_driver_template(virtnetworkd) +files_type(virtnetworkd_t) + +# virtnodedevd +virt_driver_template(virtnodedevd) +files_type(virtnodedevd_t) + +# virtnwfilterd +virt_driver_template(virtnwfilterd) +files_type(virtnwfilterd_t) + +# virtproxyd +virt_driver_template(virtproxyd) +files_type(virtproxyd_t) + +# virtqemud +virt_driver_template(virtqemud) +files_type(virtqemud_t) +domain_obj_id_change_exemption(virtqemud_t) + +type virtqemud_tmp_t; +files_tmp_file(virtqemud_tmp_t) + +# virtsecretd +virt_driver_template(virtsecretd) +files_type(virtsecretd_t) + +# virtstoraged +virt_driver_template(virtstoraged) +files_type(virtstoraged_t) + +type virtstoraged_tmp_t; +files_tmp_file(virtstoraged_tmp_t) + +# virtvboxd +virt_driver_template(virtvboxd) +files_type(virtvboxd_t) + +# virtvzd +virt_driver_template(virtvzd) +files_type(virtvzd_t) + +# virtxend +virt_driver_template(virtxend) +files_type(virtxend_t) + +######################################## +# +# Declarations +# +attribute svirt_sandbox_domain; + +type virtd_lxc_t, virt_system_domain; +type virtd_lxc_exec_t, virt_file_type; +init_system_domain(virtd_lxc_t, virtd_lxc_exec_t) + +type virt_lxc_var_run_t, virt_file_type; +files_pid_file(virt_lxc_var_run_t) +typealias virt_lxc_var_run_t alias virtd_lxc_var_run_t; + +# virt lxc container files +type container_file_t, svirt_file_type; +typealias container_file_t alias { svirt_sandbox_file_t svirt_lxc_file_t }; +files_mountpoint(container_file_t) + +type container_ro_file_t, svirt_file_type; +files_mountpoint(container_ro_file_t) + +######################################## +# +# svirt local policy +# + +allow svirt_t self:process ptrace; + +# it was a part of auth_use_nsswitch +allow svirt_t self:netlink_route_socket r_netlink_socket_perms; + +read_files_pattern(svirt_t, virtqemud_t, virtqemud_t) + +corenet_udp_sendrecv_generic_if(svirt_t) +corenet_udp_sendrecv_generic_node(svirt_t) +corenet_udp_sendrecv_all_ports(svirt_t) +corenet_udp_bind_generic_node(svirt_t) +corenet_udp_bind_all_ports(svirt_t) +corenet_tcp_bind_all_ports(svirt_t) +corenet_tcp_connect_all_ports(svirt_t) + +init_dontaudit_read_state(svirt_t) + +virt_dontaudit_read_state(svirt_t) + +storage_rw_inherited_fixed_disk_dev(svirt_t) + +userdom_read_all_users_state(svirt_t) + +####################################### +# +# svirt_prot_exec local policy +# + +allow svirt_tcg_t self:process { execmem execstack }; +allow svirt_tcg_t self:netlink_route_socket r_netlink_socket_perms; + +corenet_udp_sendrecv_generic_if(svirt_tcg_t) +corenet_udp_sendrecv_generic_node(svirt_tcg_t) +corenet_udp_sendrecv_all_ports(svirt_tcg_t) +corenet_udp_bind_generic_node(svirt_tcg_t) +corenet_udp_bind_all_ports(svirt_tcg_t) +corenet_tcp_bind_all_ports(svirt_tcg_t) +corenet_tcp_connect_all_ports(svirt_tcg_t) + +ps_process_pattern(svirt_tcg_t, virtd_t) + +virt_dontaudit_read_state(svirt_tcg_t) + +######################################## +# +# virtd local policy +# + +# fsetid - for chmod'ing its runtime files +allow virtd_t self:capability { chown dac_read_search fowner fsetid ipc_lock kill mknod net_admin net_raw setgid setpcap setuid sys_admin sys_nice sys_ptrace }; +#allow virtd_t self:capability2 compromise_kernel; +allow virtd_t self:process { execmem getcap getsched setcap setexec setfscreate setsched setsockcreate sigkill signal signull }; +ifdef(`hide_broken_symptoms',` + # caused by some bogus kernel code + dontaudit virtd_t self:capability { sys_module }; +') + +allow virtd_t self:fifo_file { manage_fifo_file_perms relabelfrom relabelto }; +allow virtd_t self:unix_stream_socket { connectto create_stream_socket_perms relabelfrom relabelto }; +allow virtd_t self:tcp_socket create_stream_socket_perms; +allow virtd_t self:tun_socket { create_socket_perms relabelfrom relabelto }; +allow virtd_t self:rawip_socket create_socket_perms; +allow virtd_t self:packet_socket create_socket_perms; +allow virtd_t self:netlink_kobject_uevent_socket create_socket_perms; +allow virtd_t self:netlink_route_socket create_netlink_socket_perms; +allow virtd_t self:netlink_socket create_socket_perms; +allow virtd_t self:netlink_generic_socket create_socket_perms; + +manage_dirs_pattern(virtd_t, virt_cache_t, virt_cache_t) +manage_files_pattern(virtd_t, virt_cache_t, virt_cache_t) +files_var_filetrans(virtd_t, virt_cache_t, dir) + +manage_dirs_pattern(virtd_t, virt_content_t, virt_content_t) +manage_files_pattern(virtd_t, virt_content_t, virt_content_t) + +allow virtd_t virtd_keytab_t:file read_file_perms; + +allow virtd_t virt_domain:process { getattr getsched setsched sigkill signal signull transition }; +allow virtd_t svirt_sandbox_domain:process { getattr getsched setsched sigkill signal signull transition }; +allow virt_domain virtd_t:fd use; +allow virt_domain virtd_t:unix_stream_socket { accept getattr getopt read write }; +allow virtd_t virt_domain:unix_stream_socket { connectto create_stream_socket_perms }; +allow virt_domain virtd_t:tun_socket attach_queue; + +can_exec(virtd_t, qemu_exec_t) +can_exec(virt_domain, qemu_exec_t) + +allow virtd_t qemu_var_run_t:file relabel_file_perms; +manage_dirs_pattern(virtd_t, qemu_var_run_t, qemu_var_run_t) +relabelfrom_dirs_pattern(virtd_t, qemu_var_run_t, qemu_var_run_t) +manage_files_pattern(virtd_t, qemu_var_run_t, qemu_var_run_t) +relabelfrom_files_pattern(virtd_t, qemu_var_run_t, qemu_var_run_t) +manage_sock_files_pattern(virtd_t, qemu_var_run_t, qemu_var_run_t) +stream_connect_pattern(virtd_t, qemu_var_run_t, qemu_var_run_t, virt_domain) +filetrans_pattern(virtd_t, virt_var_run_t, qemu_var_run_t, dir, "qemu") + +read_files_pattern(virtd_t, virt_etc_t, virt_etc_t) +read_lnk_files_pattern(virtd_t, virt_etc_t, virt_etc_t) + +manage_dirs_pattern(virtd_t, virt_etc_rw_t, virt_etc_rw_t) +manage_files_pattern(virtd_t, virt_etc_rw_t, virt_etc_rw_t) +manage_lnk_files_pattern(virtd_t, virt_etc_rw_t, virt_etc_rw_t) +filetrans_pattern(virtd_t, virt_etc_t, virt_etc_rw_t, dir) + +relabelto_dirs_pattern(virtd_t, virt_image_type, virt_image_type) +manage_files_pattern(virtd_t, virt_image_type, virt_image_type) +manage_chr_files_pattern(virtd_t, virt_image_type, virt_image_type) +manage_blk_files_pattern(virtd_t, virt_image_type, virt_image_type) +manage_lnk_files_pattern(virtd_t, virt_image_type, virt_image_type) +allow virtd_t virt_image_type:dir { rmdir setattr }; +allow virtd_t virt_image_type:file relabel_file_perms; +allow virtd_t virt_image_type:blk_file relabel_blk_file_perms; +allow virtd_t virt_image_type:chr_file relabel_chr_file_perms; +allow virtd_t virt_image_type:unix_stream_socket { getattr relabelfrom relabelto }; +allow virtd_t virt_ptynode:chr_file rw_term_perms; + +manage_dirs_pattern(virtd_t, virt_tmp_t, virt_tmp_t) +manage_files_pattern(virtd_t, virt_tmp_t, virt_tmp_t) +files_tmp_filetrans(virtd_t, virt_tmp_t, { file dir }) +can_exec(virtd_t, virt_tmp_t) + +manage_dirs_pattern(virtd_t, virt_lock_t, virt_lock_t) +manage_files_pattern(virtd_t, virt_lock_t, virt_lock_t) +manage_lnk_files_pattern(virtd_t, virt_lock_t, virt_lock_t) +files_lock_filetrans(virtd_t, virt_lock_t, { dir file lnk_file }) + +manage_dirs_pattern(virtd_t, virt_log_t, virt_log_t) +manage_files_pattern(virtd_t, virt_log_t, virt_log_t) +logging_log_filetrans(virtd_t, virt_log_t, { file dir }) + +manage_dirs_pattern(virtd_t, virt_var_lib_t, virt_var_lib_t) +manage_files_pattern(virtd_t, virt_var_lib_t, virt_var_lib_t) +manage_sock_files_pattern(virtd_t, virt_var_lib_t, virt_var_lib_t) +files_var_lib_filetrans(virtd_t, virt_var_lib_t, { file dir }) +allow virtd_t virt_var_lib_t:file { relabelfrom relabelto }; + +manage_dirs_pattern(virtlogd_t, virt_var_lockd_t, virt_var_lockd_t) +manage_files_pattern(virtlogd_t, virt_var_lockd_t, virt_var_lockd_t) +filetrans_pattern(virtlogd_t, virt_var_lib_t, virt_var_lockd_t, dir, "lockd") + +manage_dirs_pattern(virtd_t, virt_var_run_t, virt_var_run_t) +manage_files_pattern(virtd_t, virt_var_run_t, virt_var_run_t) +manage_sock_files_pattern(virtd_t, virt_var_run_t, virt_var_run_t) +files_pid_filetrans(virtd_t, virt_var_run_t, { file dir sock_file }) + +manage_dirs_pattern(virtd_t, virt_driver_var_run, virt_driver_var_run) +manage_files_pattern(virtd_t, virt_driver_var_run, virt_driver_var_run) +manage_sock_files_pattern(virtd_t, virt_driver_var_run, virt_driver_var_run) + +manage_dirs_pattern(virtd_t, virt_lxc_var_run_t, virt_lxc_var_run_t) +manage_files_pattern(virtd_t, virt_lxc_var_run_t, virt_lxc_var_run_t) +filetrans_pattern(virtd_t, virt_var_run_t, virt_lxc_var_run_t, dir, "lxc") +allow virtd_t virt_lxc_var_run_t:file { relabelfrom relabelto }; +stream_connect_pattern(virtd_t, virt_lxc_var_run_t, virt_lxc_var_run_t, virtd_lxc_t) + +# libvirtd is permitted to talk to virtlogd +stream_connect_pattern(virtd_t, virt_var_run_t, virtlogd_var_run_t, virtlogd_t) +allow virtd_t virtlogd_t:fifo_file rw_inherited_fifo_file_perms; + +kernel_read_system_state(virtd_t) +kernel_read_network_state(virtd_t) +kernel_rw_net_sysctls(virtd_t) +kernel_read_kernel_sysctls(virtd_t) +kernel_request_load_module(virtd_t) +kernel_search_debugfs(virtd_t) +kernel_dontaudit_setsched(virtd_t) +kernel_write_proc_files(virtd_t) + +corecmd_exec_bin(virtd_t) +corecmd_exec_shell(virtd_t) + +corenet_all_recvfrom_netlabel(virtd_t) +corenet_tcp_sendrecv_generic_if(virtd_t) +corenet_tcp_sendrecv_generic_node(virtd_t) +corenet_tcp_sendrecv_all_ports(virtd_t) +corenet_tcp_bind_generic_node(virtd_t) +corenet_tcp_bind_virt_port(virtd_t) +corenet_tcp_bind_vnc_port(virtd_t) +corenet_tcp_connect_vnc_port(virtd_t) +corenet_tcp_connect_soundd_port(virtd_t) +corenet_rw_tun_tap_dev(virtd_t) +corenet_relabel_tun_tap_dev(virtd_t) + +dev_rw_vfio_dev(virtd_t) +dev_rw_sysfs(virtd_t) +dev_read_urand(virtd_t) +dev_read_rand(virtd_t) +dev_rw_kvm(virtd_t) +dev_getattr_all_chr_files(virtd_t) +dev_rw_mtrr(virtd_t) +dev_rw_vhost(virtd_t) +dev_setattr_generic_usb_dev(virtd_t) +dev_relabel_generic_usb_dev(virtd_t) + +# Init script handling +domain_use_interactive_fds(virtd_t) +domain_read_all_domains_state(virtd_t) +domain_signull_all_domains(virtd_t) + +files_list_all_mountpoints(virtd_t) +files_read_etc_runtime_files(virtd_t) +files_search_all(virtd_t) +files_read_kernel_modules(virtd_t) +files_read_usr_src_files(virtd_t) +files_relabelto_system_conf_files(virtd_t) +files_relabelfrom_system_conf_files(virtd_t) +files_relabelfrom_boot_files(virtd_t) +files_relabelto_boot_files(virtd_t) +files_manage_boot_files(virtd_t) + +# Manages /etc/sysconfig/system-config-firewall +files_manage_system_conf_files(virtd_t) + +fs_read_tmpfs_symlinks(virtd_t) +fs_list_auto_mountpoints(virtd_t) +fs_getattr_all_fs(virtd_t) +fs_rw_anon_inodefs_files(virtd_t) +fs_list_inotifyfs(virtd_t) +fs_manage_cgroup_dirs(virtd_t) +fs_rw_cgroup_files(virtd_t) +fs_manage_hugetlbfs_dirs(virtd_t) +fs_rw_hugetlbfs_files(virtd_t) + +mls_fd_share_all_levels(virtd_t) +mls_file_read_to_clearance(virtd_t) +mls_file_write_to_clearance(virtd_t) +mls_process_read_to_clearance(virtd_t) +mls_process_write_to_clearance(virtd_t) +mls_net_write_within_range(virtd_t) +mls_socket_write_to_clearance(virtd_t) +mls_socket_read_to_clearance(virtd_t) +mls_rangetrans_source(virtd_t) +mls_file_upgrade(virtd_t) + +mcs_process_set_categories(virtd_t) + +storage_manage_fixed_disk(virtd_t) +storage_relabel_fixed_disk(virtd_t) +storage_raw_write_removable_device(virtd_t) +storage_raw_read_removable_device(virtd_t) + +term_getattr_pty_fs(virtd_t) +term_use_generic_ptys(virtd_t) +term_use_ptmx(virtd_t) + +auth_use_nsswitch(virtd_t) + +init_dbus_chat(virtd_t) +init_read_utmp(virtd_t) + +miscfiles_read_generic_certs(virtd_t) +miscfiles_read_hwdata(virtd_t) + +modutils_read_module_deps(virtd_t) +modutils_read_module_config(virtd_t) +modutils_manage_module_config(virtd_t) + +logging_send_syslog_msg(virtd_t) +logging_send_audit_msgs(virtd_t) +logging_stream_connect_syslog(virtd_t) + +selinux_validate_context(virtd_t) + +seutil_read_config(virtd_t) +seutil_read_default_contexts(virtd_t) +seutil_read_file_contexts(virtd_t) + +sysnet_signull_ifconfig(virtd_t) +sysnet_signal_ifconfig(virtd_t) +sysnet_domtrans_ifconfig(virtd_t) +sysnet_read_config(virtd_t) + +systemd_dbus_chat_logind(virtd_t) +systemd_write_inhibit_pipes(virtd_t) + +userdom_list_admin_dir(virtd_t) +userdom_getattr_all_users(virtd_t) +userdom_list_user_home_content(virtd_t) +userdom_read_all_users_state(virtd_t) +userdom_read_user_home_content_files(virtd_t) +userdom_relabel_user_tmp_files(virtd_t) +userdom_setattr_user_tmp_files(virtd_t) +userdom_relabel_user_home_files(virtd_t) +userdom_setattr_user_home_content_files(virtd_t) +manage_dirs_pattern(virtd_t, virt_home_t, virt_home_t) +manage_files_pattern(virtd_t, virt_home_t, virt_home_t) +manage_sock_files_pattern(virtd_t, virt_home_t, virt_home_t) +manage_lnk_files_pattern(virtd_t, virt_home_t, virt_home_t) +#userdom_user_home_dir_filetrans(virtd_t, virt_home_t, { dir file }) +virt_filetrans_home_content(virtd_t) + +tunable_policy(`virt_use_nfs',` + fs_manage_nfs_dirs(virtd_t) + fs_manage_nfs_files(virtd_t) + fs_mmap_nfs_files(virtd_t) + fs_read_nfs_symlinks(virtd_t) +') + +tunable_policy(`virt_use_samba',` + fs_manage_cifs_dirs(virtd_t) + fs_manage_cifs_files(virtd_t) + fs_read_cifs_symlinks(virtd_t) +') + +optional_policy(` + brctl_domtrans(virtd_t) +') + +optional_policy(` + consoletype_exec(virtd_t) +') + +optional_policy(` + dbus_system_bus_client(virtd_t) + + optional_policy(` + avahi_dbus_chat(virtd_t) + ') + + optional_policy(` + consolekit_dbus_chat(virtd_t) + ') + + optional_policy(` + networkmanager_dbus_chat(virtd_t) + ') +') + +optional_policy(` + dmidecode_domtrans(virtd_t) +') + +optional_policy(` + dnsmasq_domtrans(virtd_t) + dnsmasq_signal(virtd_t) + dnsmasq_kill(virtd_t) + dnsmasq_signull(virtd_t) + dnsmasq_create_pid_dirs(virtd_t) + dnsmasq_filetrans_named_content_fromdir(virtd_t, virt_var_run_t) + dnsmasq_manage_pid_files(virtd_t) +') + +optional_policy(` + firewalld_dbus_chat(virtd_t) +') + +optional_policy(` + iptables_domtrans(virtd_t) + iptables_initrc_domtrans(virtd_t) + iptables_systemctl(virtd_t) + + # Manages /etc/sysconfig/system-config-firewall + iptables_manage_config(virtd_t) +') + +optional_policy(` + kerberos_read_keytab(virtd_t) + kerberos_use(virtd_t) +') + +optional_policy(` + kernel_read_xen_state(virtd_t) + kernel_write_xen_state(virtd_t) + + xen_exec(virtd_t) + xen_stream_connect(virtd_t) + xen_stream_connect_xenstore(virtd_t) + xen_read_image_files(virtd_t) +') + +optional_policy(` + lvm_domtrans(virtd_t) +') + +optional_policy(` + # Run mount in the mount_t domain. + mount_domtrans(virtd_t) + mount_signal(virtd_t) +') + +optional_policy(` + numad_domtrans(virtd_t) + numad_dbus_chat(virtd_t) +') + +optional_policy(` + policykit_dbus_chat(virtd_t) + policykit_domtrans_auth(virtd_t) + policykit_domtrans_resolve(virtd_t) + policykit_read_lib(virtd_t) +') + +optional_policy(` + qemu_exec(virtd_t) +') + +optional_policy(` + sanlock_stream_connect(virtd_t) +') + +optional_policy(` + sasl_connect(virtd_t) +') + +optional_policy(` + setrans_manage_pid_files(virtd_t) +') + +optional_policy(` + udev_domtrans(virtd_t) + udev_read_db(virtd_t) + udev_read_pid_files(virtd_t) +') + +optional_policy(` + unconfined_domain(virtd_t) +') + +######################################## +# +# virtlogd local policy +# + +# virtlogd is allowed to manage files it creates in /var/run/libvirt +manage_files_pattern(virtlogd_t, virt_var_run_t, virtlogd_var_run_t) + +# virtlogd needs to read /etc/libvirt/virtlogd.conf only +allow virtlogd_t virtlogd_etc_t:file read_file_perms; +files_search_etc(virtlogd_t) +allow virtlogd_t virt_etc_t:file read_file_perms; +allow virtlogd_t virt_etc_t:lnk_file { read_lnk_file_perms ioctl lock }; +allow virtlogd_t virt_etc_t:dir search; + +manage_dirs_pattern(virtlogd_t, virt_etc_rw_t, virt_etc_rw_t) +manage_files_pattern(virtlogd_t, virt_etc_rw_t, virt_etc_rw_t) +manage_lnk_files_pattern(virtlogd_t, virt_etc_rw_t, virt_etc_rw_t) +filetrans_pattern(virtlogd_t, virt_etc_t, virt_etc_rw_t, dir) + +# virtlogd creates /var/run/libvirt/virtlogd-sock with isolated +# context from other stuff in /var/run/libvirt +filetrans_pattern(virtlogd_t, virt_var_run_t, virtlogd_var_run_t, { sock_file }) +# This lets systemd create the socket itself too + +# virtlogd creates a /var/run/virtlogd.pid file +allow virtlogd_t virtlogd_var_run_t:file manage_file_perms; +manage_sock_files_pattern(virtlogd_t, virt_var_run_t, virtlogd_var_run_t) +files_pid_filetrans(virtlogd_t, virtlogd_var_run_t, file) + +manage_dirs_pattern(virtlogd_t, svirt_tmp_t, svirt_tmp_t) +manage_files_pattern(virtlogd_t, svirt_tmp_t, svirt_tmp_t) +manage_lnk_files_pattern(virtlogd_t, svirt_tmp_t, svirt_tmp_t) +files_tmp_filetrans(virtlogd_t, svirt_tmp_t, { file dir lnk_file }) + +manage_dirs_pattern(virtlogd_t, virt_tmp_t, virt_tmp_t) +manage_files_pattern(virtlogd_t, virt_tmp_t, virt_tmp_t) + +can_exec(virtlogd_t, virtlogd_exec_t) + +kernel_read_network_state(virtlogd_t) + +allow virtlogd_t self:unix_stream_socket create_stream_socket_perms; + +# Allow virtlogd_t to execute itself. +allow virtlogd_t virtlogd_exec_t:file execute_no_trans; + +dev_read_sysfs(virtlogd_t) + +logging_send_syslog_msg(virtlogd_t) + +auth_use_nsswitch(virtlogd_t) + +manage_files_pattern(virtlogd_t, virt_log_t, virt_log_t) + +manage_files_pattern(virtlogd_t, svirt_image_t, svirt_image_t) + +# Allow virtlogd to look at /proc/$PID/status +# to authenticate the connecting libvirtd +allow virtlogd_t virtd_t:dir list_dir_perms; +allow virtlogd_t virtd_t:file read_file_perms; +allow virtlogd_t virtd_t:lnk_file read_lnk_file_perms; + +read_files_pattern(virtlogd_t, virtqemud_t, virtqemud_t) + +virt_manage_lib_files(virtlogd_t) + +tunable_policy(`virt_lockd_blk_devs',` + dev_lock_all_blk_files(virtlogd_t) +') + +tunable_policy(`virt_use_nfs',` + fs_append_nfs_files(virtlogd_t) +') + +optional_policy(` + dbus_system_bus_client(virtlogd_t) +') + +optional_policy(` + systemd_write_inhibit_pipes(virtlogd_t) + systemd_dbus_chat_logind(virtlogd_t) +') + +######################################## +# +# virtual domains common policy +# +#allow virt_domain self:capability2 compromise_kernel; +allow virt_domain self:process { getsched setrlimit setsched signal_perms }; +allow virt_domain self:fifo_file rw_fifo_file_perms; +allow virt_domain self:shm create_shm_perms; +allow virt_domain self:unix_stream_socket { connectto create_stream_socket_perms }; +allow virt_domain self:unix_dgram_socket { create_socket_perms sendto }; +allow virt_domain self:tcp_socket create_stream_socket_perms; +allow virt_domain self:udp_socket create_socket_perms; +allow virt_domain self:icmp_socket create_socket_perms; +allow virt_domain self:netlink_kobject_uevent_socket create_socket_perms; + +list_dirs_pattern(virt_domain, virt_content_t, virt_content_t) +read_files_pattern(virt_domain, virt_content_t, virt_content_t) +dontaudit virt_domain virt_content_t:file write_file_perms; +dontaudit virt_domain virt_content_t:dir write; + +kernel_read_net_sysctls(virt_domain) +kernel_read_network_state(virt_domain) +kernel_ib_access_unlabeled_pkeys(virt_domain) + +userdom_search_user_home_content(virt_domain) +userdom_read_user_home_content_symlinks(virt_domain) +userdom_read_all_users_state(virt_domain) +append_files_pattern(virt_domain, virt_home_t, virt_home_t) +manage_dirs_pattern(virt_domain, svirt_home_t, svirt_home_t) +manage_files_pattern(virt_domain, svirt_home_t, svirt_home_t) +manage_sock_files_pattern(virt_domain, svirt_home_t, svirt_home_t) +filetrans_pattern(virt_domain, virt_home_t, svirt_home_t, { dir sock_file file }) +stream_connect_pattern(virt_domain, svirt_home_t, svirt_home_t, virtd_t) + +manage_dirs_pattern(virt_domain, virt_cache_t, virt_cache_t) +manage_files_pattern(virt_domain, virt_cache_t, virt_cache_t) +files_var_filetrans(virt_domain, virt_cache_t, { file dir }) + +read_files_pattern(virt_domain, virt_image_t, virt_image_t) +read_lnk_files_pattern(virt_domain, virt_image_t, virt_image_t) + +manage_dirs_pattern(virt_domain, svirt_image_t, svirt_image_t) +manage_files_pattern(virt_domain, svirt_image_t, svirt_image_t) +manage_sock_files_pattern(virt_domain, svirt_image_t, svirt_image_t) +manage_fifo_files_pattern(virt_domain, svirt_image_t, svirt_image_t) +read_lnk_files_pattern(virt_domain, svirt_image_t, svirt_image_t) +rw_chr_files_pattern(virt_domain, svirt_image_t, svirt_image_t) +rw_blk_files_pattern(virt_domain, svirt_image_t, svirt_image_t) +fs_hugetlbfs_filetrans(virt_domain, svirt_image_t, file) +allow svirt_t svirt_image_t:file map; +allow svirt_t svirt_image_t:blk_file map; + +manage_dirs_pattern(virt_domain, svirt_tmp_t, svirt_tmp_t) +manage_files_pattern(virt_domain, svirt_tmp_t, svirt_tmp_t) +manage_lnk_files_pattern(virt_domain, svirt_tmp_t, svirt_tmp_t) +manage_sock_files_pattern(virt_domain, svirt_tmp_t, svirt_tmp_t) +files_tmp_filetrans(virt_domain, svirt_tmp_t, { file dir lnk_file sock_file}) +userdom_user_tmp_filetrans(virt_domain, svirt_tmp_t, { dir file lnk_file }) + +manage_dirs_pattern(virt_domain, svirt_tmpfs_t, svirt_tmpfs_t) +manage_files_pattern(virt_domain, svirt_tmpfs_t, svirt_tmpfs_t) +manage_lnk_files_pattern(virt_domain, svirt_tmpfs_t, svirt_tmpfs_t) +fs_tmpfs_filetrans(virt_domain, svirt_tmpfs_t, { dir file lnk_file }) +allow virt_domain svirt_tmpfs_t:file map; + +manage_dirs_pattern(virt_domain, qemu_var_run_t, qemu_var_run_t) +manage_files_pattern(virt_domain, qemu_var_run_t, qemu_var_run_t) +manage_sock_files_pattern(virt_domain, qemu_var_run_t, qemu_var_run_t) +manage_lnk_files_pattern(virt_domain, qemu_var_run_t, qemu_var_run_t) +files_pid_filetrans(virt_domain, qemu_var_run_t, { dir file }) +stream_connect_pattern(virt_domain, qemu_var_run_t, qemu_var_run_t, virtd_t) + +dontaudit virtd_t virt_domain:process { noatsecure rlimitinh siginh}; + +dontaudit virt_domain virt_tmpfs_type:file { read write }; + +append_files_pattern(virt_domain, virt_log_t, virt_log_t) + +append_files_pattern(virt_domain, virt_var_lib_t, virt_var_lib_t) + +corecmd_exec_bin(virt_domain) +corecmd_exec_shell(virt_domain) + +corenet_tcp_sendrecv_generic_if(virt_domain) +corenet_tcp_sendrecv_generic_node(virt_domain) +corenet_tcp_sendrecv_all_ports(virt_domain) +corenet_tcp_bind_generic_node(virt_domain) +corenet_tcp_bind_vnc_port(virt_domain) +corenet_tcp_bind_virt_migration_port(virt_domain) +corenet_tcp_connect_virt_migration_port(virt_domain) +corenet_rw_inherited_tun_tap_dev(virt_domain) + +dev_list_sysfs(virt_domain) +dev_getattr_fs(virt_domain) +dev_dontaudit_getattr_all(virt_domain) +dev_read_generic_symlinks(virt_domain) +dev_read_rand(virt_domain) +dev_read_sound(virt_domain) +dev_read_urand(virt_domain) +dev_write_sound(virt_domain) +dev_rw_ksm(virt_domain) +dev_rw_vfio_dev(virt_domain) +dev_rw_kvm(virt_domain) +dev_rw_sev(virt_domain) +dev_rw_qemu(virt_domain) +dev_rw_inherited_vhost(virt_domain) +dev_rw_infiniband_dev(virt_domain) +dev_rw_dri(virt_domain) +dev_rw_tpm(virt_domain) +dev_rw_xserver_misc(virt_domain) + +domain_use_interactive_fds(virt_domain) + +files_read_mnt_symlinks(virt_domain) +files_read_var_files(virt_domain) +files_search_all(virt_domain) + +fs_rw_cephfs_files(virt_domain) +fs_getattr_xattr_fs(virt_domain) +fs_getattr_tmpfs(virt_domain) +fs_rw_anon_inodefs_files(virt_domain) +fs_rw_inherited_tmpfs_files(virt_domain) +fs_getattr_hugetlbfs(virt_domain) +fs_rw_inherited_nfs_files(virt_domain) +fs_rw_inherited_cifs_files(virt_domain) +fs_rw_inherited_noxattr_fs_files(virt_domain) + +# I think we need these for now. +miscfiles_read_public_files(virt_domain) +miscfiles_read_generic_certs(virt_domain) + +storage_raw_read_removable_device(virt_domain) + +sysnet_read_config(virt_domain) + +term_use_all_inherited_terms(virt_domain) +term_getattr_pty_fs(virt_domain) +term_use_generic_ptys(virt_domain) +term_use_ptmx(virt_domain) + +tunable_policy(`use_ecryptfs_home_dirs',` + fs_manage_ecryptfs_files(virt_domain) +') + +tunable_policy(`virt_use_comm',` + term_use_unallocated_ttys(virt_domain) + dev_rw_printer(virt_domain) +') + +tunable_policy(`virt_use_execmem',` + allow virt_domain self:process { execmem execstack }; +') + +tunable_policy(`virt_use_fusefs',` + fs_manage_fusefs_dirs(virt_domain) + fs_manage_fusefs_files(virt_domain) + fs_read_fusefs_symlinks(virt_domain) + fs_getattr_fusefs(virt_domain) +') + +tunable_policy(`virt_use_nfs',` + fs_manage_nfs_dirs(virt_domain) + fs_manage_nfs_files(virt_domain) + fs_manage_nfs_named_sockets(virt_domain) + fs_read_nfs_symlinks(virt_domain) + fs_getattr_nfs(virt_domain) + fs_mmap_nfs_files(virt_domain) +') + +tunable_policy(`virt_use_rawip',` + allow virt_domain self:rawip_socket create_socket_perms; +') + +tunable_policy(`virt_use_samba',` + fs_manage_cifs_dirs(virt_domain) + fs_manage_cifs_files(virt_domain) + fs_manage_cifs_named_sockets(virt_domain) + fs_read_cifs_symlinks(virt_domain) + fs_getattr_cifs(virt_domain) +') + +tunable_policy(`virt_use_usb',` + dev_rw_usbfs(virt_domain) + dev_read_sysfs(virt_domain) + fs_getattr_dos_fs(virt_domain) + fs_manage_dos_dirs(virt_domain) + fs_manage_dos_files(virt_domain) + udev_read_db(virt_domain) +') + +optional_policy(` + tunable_policy(`virt_use_glusterd',` + glusterd_manage_pid(virt_domain) + ') +') + +optional_policy(` + tunable_policy(`virt_use_pcscd',` + pcscd_stream_connect(virt_domain) + ') +') + +optional_policy(` + tunable_policy(`virt_use_sanlock',` + sanlock_stream_connect(virt_domain) + sanlock_read_state(virt_domain) + ') +') + +optional_policy(` + tunable_policy(`virt_use_xserver',` + xserver_stream_connect(virt_domain) + ') +') + +optional_policy(` + alsa_read_rw_config(virt_domain) +') + +optional_policy(` + gnome_dontaudit_manage_cache_home_dir(virt_domain) +') + +optional_policy(` + nscd_dontaudit_read_pid(virt_domain) +') + +optional_policy(` + nscd_dontaudit_write_sock_file(virt_domain) +') + +optional_policy(` + openvswitch_stream_connect(svirt_t) +') + +optional_policy(` + ptchown_domtrans(virt_domain) +') + +optional_policy(` + pulseaudio_dontaudit_exec(virt_domain) +') + +optional_policy(` + sssd_dontaudit_stream_connect(virt_domain) + sssd_dontaudit_read_lib(virt_domain) +') + +optional_policy(` + sssd_read_public_files(virt_domain) +') + +optional_policy(` + unconfined_dontaudit_read_state(virt_domain) +') + +optional_policy(` + virt_read_config(virt_domain) + virt_read_lib_files(virt_domain) + virt_read_content(virt_domain) + virt_stream_connect(virt_domain) + virt_read_pid_symlinks(virt_domain) + virt_domtrans_bridgehelper(virt_domain) +') + +optional_policy(` + xserver_rw_shm(virt_domain) +') + +######################################## +# +# xm local policy +# +type virsh_t, virt_system_domain; +type virsh_exec_t, virt_file_type; +init_system_domain(virsh_t, virsh_exec_t) +typealias virsh_t alias xm_t; +typealias virsh_exec_t alias xm_exec_t; + +allow virsh_t self:capability { dac_read_search ipc_lock setpcap sys_admin sys_chroot sys_nice sys_tty_config }; +allow virsh_t self:process { getcap getsched setcap setexec setsched signal }; +allow virsh_t self:fifo_file rw_fifo_file_perms; +allow virsh_t self:unix_stream_socket { connectto create_stream_socket_perms }; +allow virsh_t self:tcp_socket create_stream_socket_perms; + +ps_process_pattern(virsh_t, svirt_sandbox_domain) + +can_exec(virsh_t, virsh_exec_t) +virt_domtrans(virsh_t) +virt_manage_images(virsh_t) +virt_manage_config(virsh_t) +virt_stream_connect(virsh_t) + +manage_dirs_pattern(virsh_t, virt_lock_t, virt_lock_t) +manage_files_pattern(virsh_t, virt_lock_t, virt_lock_t) +manage_lnk_files_pattern(virsh_t, virt_lock_t, virt_lock_t) +files_lock_filetrans(virsh_t, virt_lock_t, { dir file lnk_file }) + +manage_files_pattern(virsh_t, virt_image_type, virt_image_type) +manage_blk_files_pattern(virsh_t, virt_image_type, virt_image_type) +manage_lnk_files_pattern(virsh_t, virt_image_type, virt_image_type) + +manage_dirs_pattern(virsh_t, container_file_t, container_file_t) +manage_files_pattern(virsh_t, container_file_t, container_file_t) +manage_chr_files_pattern(virsh_t, container_file_t, container_file_t) +manage_lnk_files_pattern(virsh_t, container_file_t, container_file_t) +manage_sock_files_pattern(virsh_t, container_file_t, container_file_t) +manage_fifo_files_pattern(virsh_t, container_file_t, container_file_t) +virt_transition_svirt_sandbox(virsh_t, system_r) + +manage_dirs_pattern(virsh_t, virt_lxc_var_run_t, virt_lxc_var_run_t) +manage_files_pattern(virsh_t, virt_lxc_var_run_t, virt_lxc_var_run_t) +virt_filetrans_named_content(virsh_t) +filetrans_pattern(virsh_t, virt_var_run_t, virt_lxc_var_run_t, dir, "lxc") + +dontaudit virsh_t virt_var_lib_t:file read_inherited_file_perms; + +kernel_write_proc_files(virsh_t) +kernel_read_system_state(virsh_t) +kernel_read_network_state(virsh_t) +kernel_read_kernel_sysctls(virsh_t) +kernel_read_sysctl(virsh_t) +kernel_read_xen_state(virsh_t) +kernel_write_xen_state(virsh_t) + +corecmd_exec_bin(virsh_t) +corecmd_exec_shell(virsh_t) + +corenet_tcp_sendrecv_generic_if(virsh_t) +corenet_tcp_sendrecv_generic_node(virsh_t) +corenet_tcp_connect_soundd_port(virsh_t) + +dev_read_rand(virsh_t) +dev_read_urand(virsh_t) +dev_read_sysfs(virsh_t) + +files_read_etc_runtime_files(virsh_t) +files_list_mnt(virsh_t) +files_list_tmp(virsh_t) +# Some common macros (you might be able to remove some) + +fs_getattr_all_fs(virsh_t) +fs_manage_xenfs_dirs(virsh_t) +fs_manage_xenfs_files(virsh_t) +fs_search_auto_mountpoints(virsh_t) + +storage_raw_read_fixed_disk(virsh_t) + +term_use_all_inherited_terms(virsh_t) +term_dontaudit_use_generic_ptys(virsh_t) + +userdom_search_admin_dir(virsh_t) +userdom_read_home_certs(virsh_t) + +init_stream_connect_script(virsh_t) +init_rw_script_stream_sockets(virsh_t) +init_use_fds(virsh_t) + +systemd_exec_systemctl(virsh_t) + +auth_read_passwd(virsh_t) + +logging_send_syslog_msg(virsh_t) + +sysnet_dns_name_resolve(virsh_t) + +userdom_stream_connect(virsh_t) + +tunable_policy(`virt_use_nfs',` + fs_manage_nfs_dirs(virsh_t) + fs_manage_nfs_files(virsh_t) + fs_read_nfs_symlinks(virsh_t) +') + +tunable_policy(`virt_use_samba',` + fs_manage_cifs_files(virsh_t) + fs_manage_cifs_files(virsh_t) + fs_read_cifs_symlinks(virsh_t) +') + +optional_policy(` + cron_system_entry(virsh_t, virsh_exec_t) +') + +optional_policy(` + dbus_system_bus_client(virsh_t) +') + +optional_policy(` + rhcs_domtrans_fenced(virsh_t) +') + +optional_policy(` + rpm_exec(virsh_t) +') + +optional_policy(` + vhostmd_rw_tmpfs_files(virsh_t) + vhostmd_stream_connect(virsh_t) + vhostmd_dontaudit_rw_stream_connect(virsh_t) +') + +optional_policy(` + ssh_basic_client_template(virsh, virsh_t, system_r) + + kernel_read_xen_state(virsh_ssh_t) + kernel_write_xen_state(virsh_ssh_t) + + dontaudit virsh_ssh_t virsh_transition_domain:fifo_file rw_inherited_fifo_file_perms; + files_search_tmp(virsh_ssh_t) + + fs_manage_xenfs_dirs(virsh_ssh_t) + fs_manage_xenfs_files(virsh_ssh_t) + + userdom_search_admin_dir(virsh_ssh_t) +') + +optional_policy(` + xen_manage_image_dirs(virsh_t) + xen_read_image_files(virsh_t) + xen_read_lib_files(virsh_t) + xen_append_log(virsh_t) + xen_domtrans(virsh_t) + xen_read_pid_files_xenstored(virsh_t) + xen_stream_connect(virsh_t) + xen_stream_connect_xenstore(virsh_t) +') + +######################################## +# +# virt_lxc local policy +# +allow virtd_lxc_t self:bpf { map_create map_read map_write prog_load prog_run }; +allow virtd_lxc_t self:capability { chown dac_read_search net_admin net_raw setgid setpcap setuid sys_admin sys_boot sys_nice sys_resource }; +allow virtd_lxc_t self:process { setpgid setsockcreate signal_perms transition }; +#allow virtd_lxc_t self:capability2 compromise_kernel; + +allow virtd_lxc_t self:process { getcap setcap setexec setrlimit setsched signal_perms }; +allow virtd_lxc_t self:fifo_file rw_fifo_file_perms; +allow virtd_lxc_t self:netlink_route_socket rw_netlink_socket_perms; +allow virtd_lxc_t self:unix_stream_socket { connectto create_stream_socket_perms }; +allow virtd_lxc_t self:packet_socket create_socket_perms; +ps_process_pattern(virtd_lxc_t, svirt_sandbox_domain) +allow virtd_t virtd_lxc_t:unix_stream_socket create_stream_socket_perms; + +corecmd_entrypoint_all_executables(virtd_lxc_t) +files_entrypoint_all_mountpoint(virtd_lxc_t) + +allow virtd_lxc_t virt_image_type:dir mounton; +manage_files_pattern(virtd_lxc_t, virt_image_t, virt_image_t) + +domtrans_pattern(virtd_t, virtd_lxc_exec_t, virtd_lxc_t) +allow virtd_t virtd_lxc_t:process { getattr noatsecure signal_perms }; + +allow virtd_lxc_t virt_var_run_t:dir search_dir_perms; +manage_dirs_pattern(virtd_lxc_t, virt_lxc_var_run_t, virt_lxc_var_run_t) +manage_files_pattern(virtd_lxc_t, virt_lxc_var_run_t, virt_lxc_var_run_t) +manage_sock_files_pattern(virtd_lxc_t, virt_lxc_var_run_t, virt_lxc_var_run_t) +files_pid_filetrans(virtd_lxc_t, virt_lxc_var_run_t, { file dir }) +filetrans_pattern(virtd_lxc_t, virt_var_run_t, virt_lxc_var_run_t, dir, "lxc") + +manage_dirs_pattern(virtd_lxc_t, container_file_t, container_file_t) +manage_files_pattern(virtd_lxc_t, container_file_t, container_file_t) +manage_chr_files_pattern(virtd_lxc_t, container_file_t, container_file_t) +manage_lnk_files_pattern(virtd_lxc_t, container_file_t, container_file_t) +manage_sock_files_pattern(virtd_lxc_t, container_file_t, container_file_t) +manage_fifo_files_pattern(virtd_lxc_t, container_file_t, container_file_t) +allow virtd_lxc_t container_file_t:dir_file_class_set { relabelfrom relabelto }; +allow virtd_lxc_t container_file_t:filesystem { relabelfrom relabelto }; +files_associate_rootfs(container_file_t) + +seutil_read_file_contexts(virtd_lxc_t) + +storage_manage_fixed_disk(virtd_lxc_t) +storage_rw_fuse(virtd_lxc_t) + +kernel_read_all_sysctls(virtd_lxc_t) +kernel_read_network_state(virtd_lxc_t) +kernel_read_system_state(virtd_lxc_t) +kernel_request_load_module(virtd_lxc_t) + +corecmd_exec_bin(virtd_lxc_t) +corecmd_exec_shell(virtd_lxc_t) + +dev_relabel_all_dev_nodes(virtd_lxc_t) +dev_rw_sysfs(virtd_lxc_t) +dev_read_sysfs(virtd_lxc_t) +dev_read_urand(virtd_lxc_t) + +domain_use_interactive_fds(virtd_lxc_t) + +files_search_all(virtd_lxc_t) +files_getattr_all_files(virtd_lxc_t) +files_relabel_rootfs(virtd_lxc_t) +files_mounton_non_security(virtd_lxc_t) +files_mount_all_file_type_fs(virtd_lxc_t) +files_unmount_all_file_type_fs(virtd_lxc_t) +files_list_isid_type_dirs(virtd_lxc_t) +files_root_filetrans(virtd_lxc_t, container_file_t, dir_file_class_set) + +fs_read_fusefs_files(virtd_lxc_t) +fs_getattr_all_fs(virtd_lxc_t) +fs_manage_tmpfs_dirs(virtd_lxc_t) +fs_manage_tmpfs_chr_files(virtd_lxc_t) +fs_manage_tmpfs_symlinks(virtd_lxc_t) +fs_manage_cgroup_dirs(virtd_lxc_t) +fs_mounton_tmpfs(virtd_lxc_t) +fs_remount_all_fs(virtd_lxc_t) +fs_rw_cgroup_files(virtd_lxc_t) +fs_unmount_all_fs(virtd_lxc_t) +fs_relabelfrom_tmpfs(virtd_lxc_t) + +logging_send_audit_msgs(virtd_lxc_t) + +selinux_mount_fs(virtd_lxc_t) +selinux_unmount_fs(virtd_lxc_t) +seutil_read_config(virtd_lxc_t) + +term_use_generic_ptys(virtd_lxc_t) +term_use_ptmx(virtd_lxc_t) +term_relabel_pty_fs(virtd_lxc_t) + +auth_use_nsswitch(virtd_lxc_t) + +logging_send_syslog_msg(virtd_lxc_t) + +seutil_domtrans_setfiles(virtd_lxc_t) +seutil_read_default_contexts(virtd_lxc_t) + +selinux_get_enforce_mode(virtd_lxc_t) +selinux_get_fs_mount(virtd_lxc_t) +selinux_validate_context(virtd_lxc_t) +selinux_compute_access_vector(virtd_lxc_t) +selinux_compute_create_context(virtd_lxc_t) +selinux_compute_relabel_context(virtd_lxc_t) +selinux_compute_user_contexts(virtd_lxc_t) + +sysnet_exec_ifconfig(virtd_lxc_t) + +systemd_dbus_chat_machined(virtd_lxc_t) + +userdom_read_admin_home_files(virtd_lxc_t) + +optional_policy(` + dbus_system_bus_client(virtd_lxc_t) + init_dbus_chat(virtd_lxc_t) +') + +optional_policy(` + container_exec_lib(virtd_lxc_t) +') + +optional_policy(` + gnome_read_generic_cache_files(virtd_lxc_t) +') + +optional_policy(` + setrans_manage_pid_files(virtd_lxc_t) +') + +optional_policy(` + unconfined_domain(virtd_lxc_t) +') + +######################################## +# +# svirt_sandbox_domain local policy +# +allow svirt_sandbox_domain self:key manage_key_perms; +dontaudit svirt_sandbox_domain svirt_sandbox_domain:key search; + +allow svirt_sandbox_domain self:process { getattr getcap getpgid getsched setcap setpgid setrlimit setsched signal_perms }; +allow svirt_sandbox_domain self:fifo_file manage_fifo_file_perms; +allow svirt_sandbox_domain self:msg all_msg_perms; +allow svirt_sandbox_domain self:sem create_sem_perms; +allow svirt_sandbox_domain self:shm create_shm_perms; +allow svirt_sandbox_domain self:msgq create_msgq_perms; +allow svirt_sandbox_domain self:unix_stream_socket { connectto create_stream_socket_perms }; +allow svirt_sandbox_domain self:unix_dgram_socket { create_socket_perms sendto }; +allow svirt_sandbox_domain self:passwd rootok; +allow svirt_sandbox_domain self:filesystem associate; +allow svirt_sandbox_domain self:netlink_kobject_uevent_socket create_socket_perms; + +dev_dontaudit_mounton_sysfs(svirt_sandbox_domain) + +fs_dontaudit_remount_tmpfs(svirt_sandbox_domain) +fs_rw_onload_sockets(svirt_sandbox_domain) + +tunable_policy(`deny_ptrace',`',` + allow svirt_sandbox_domain self:process ptrace; +') + +allow virtd_t svirt_sandbox_domain:unix_stream_socket { connectto create_stream_socket_perms }; +allow virtd_t svirt_sandbox_domain:process { getattr signal_perms }; +allow virtd_lxc_t svirt_sandbox_domain:process { getattr getsched setrlimit setsched signal_perms transition }; + +allow svirt_sandbox_domain virtd_lxc_t:process sigchld; +allow svirt_sandbox_domain virtd_lxc_t:fd use; +allow svirt_sandbox_domain virtd_lxc_t:unix_stream_socket { connectto rw_socket_perms }; + +manage_dirs_pattern(svirt_sandbox_domain, container_file_t, container_file_t) +manage_files_pattern(svirt_sandbox_domain, container_file_t, container_file_t) +manage_lnk_files_pattern(svirt_sandbox_domain, container_file_t, container_file_t) +manage_sock_files_pattern(svirt_sandbox_domain, container_file_t, container_file_t) +manage_fifo_files_pattern(svirt_sandbox_domain, container_file_t, container_file_t) +allow svirt_sandbox_domain container_file_t:file { execmod relabelfrom relabelto }; +allow svirt_sandbox_domain container_file_t:dir { execmod relabelfrom relabelto }; +allow svirt_sandbox_domain svirt_file_type:dir_file_class_set mounton; + +list_dirs_pattern(svirt_sandbox_domain, container_file_t, container_file_t) +read_files_pattern(svirt_sandbox_domain, container_file_t, container_file_t) +read_lnk_files_pattern(svirt_sandbox_domain, container_file_t, container_file_t) +allow svirt_sandbox_domain container_file_t:file execmod; +can_exec(svirt_sandbox_domain, container_file_t) + +allow svirt_sandbox_domain container_file_t:blk_file setattr; +rw_blk_files_pattern(svirt_sandbox_domain, container_file_t, container_file_t) +can_exec(svirt_sandbox_domain, container_file_t) +allow svirt_sandbox_domain container_file_t:dir mounton; +allow svirt_sandbox_domain container_file_t:filesystem { getattr remount }; + +kernel_list_all_proc(svirt_sandbox_domain) +kernel_read_all_sysctls(svirt_sandbox_domain) +kernel_rw_net_sysctls(svirt_sandbox_domain) +kernel_rw_unix_sysctls(svirt_sandbox_domain) +kernel_dontaudit_search_kernel_sysctl(svirt_sandbox_domain) +kernel_dontaudit_access_check_proc(svirt_sandbox_domain) +kernel_dontaudit_setattr_proc_files(svirt_sandbox_domain) +kernel_dontaudit_setattr_proc_dirs(svirt_sandbox_domain) +kernel_dontaudit_write_usermodehelper_state(svirt_sandbox_domain) + +corecmd_exec_all_executables(svirt_sandbox_domain) + +domain_dontaudit_link_all_domains_keyrings(svirt_sandbox_domain) +domain_dontaudit_search_all_domains_keyrings(svirt_sandbox_domain) + +files_dontaudit_getattr_all_dirs(svirt_sandbox_domain) +files_dontaudit_getattr_all_files(svirt_sandbox_domain) +files_dontaudit_getattr_all_symlinks(svirt_sandbox_domain) +files_dontaudit_getattr_all_pipes(svirt_sandbox_domain) +files_dontaudit_getattr_all_sockets(svirt_sandbox_domain) +files_search_all_mountpoints(svirt_sandbox_domain) +files_dontaudit_list_all_mountpoints(svirt_sandbox_domain) +files_dontaudit_write_etc_runtime_files(svirt_sandbox_domain) + +files_entrypoint_all_mountpoint(svirt_sandbox_domain) +corecmd_entrypoint_all_executables(svirt_sandbox_domain) + +files_search_all(svirt_sandbox_domain) +files_read_usr_symlinks(svirt_sandbox_domain) +files_search_locks(svirt_sandbox_domain) +files_dontaudit_unmount_all_mountpoints(svirt_sandbox_domain) +fs_rw_cephfs_files(svirt_sandbox_domain) + +fs_getattr_all_fs(svirt_sandbox_domain) +fs_list_inotifyfs(svirt_sandbox_domain) +fs_rw_inherited_tmpfs_files(svirt_sandbox_domain) +fs_read_hugetlbfs_files(svirt_sandbox_domain) +fs_read_tmpfs_symlinks(svirt_sandbox_domain) +fs_search_tmpfs(svirt_sandbox_domain) +fs_rw_hugetlbfs_files(svirt_sandbox_domain) + +auth_dontaudit_read_passwd(svirt_sandbox_domain) +auth_dontaudit_read_login_records(svirt_sandbox_domain) +auth_dontaudit_write_login_records(svirt_sandbox_domain) +auth_search_pam_console_data(svirt_sandbox_domain) + +init_dontaudit_read_utmp(svirt_sandbox_domain) +init_dontaudit_write_utmp(svirt_sandbox_domain) + +libs_dontaudit_setattr_lib_files(svirt_sandbox_domain) + +miscfiles_dontaudit_access_check_cert(svirt_sandbox_domain) +miscfiles_dontaudit_setattr_fonts_cache_dirs(svirt_sandbox_domain) +miscfiles_read_fonts(svirt_sandbox_domain) +miscfiles_read_hwdata(svirt_sandbox_domain) + +userdom_use_inherited_user_terminals(svirt_sandbox_domain) +userdom_dontaudit_append_inherited_admin_home_file(svirt_sandbox_domain) +userdom_dontaudit_read_inherited_admin_home_files(svirt_sandbox_domain) + +tunable_policy(`virt_use_nfs',` + fs_manage_nfs_dirs(svirt_sandbox_domain) + fs_manage_nfs_files(svirt_sandbox_domain) + fs_manage_nfs_named_sockets(svirt_sandbox_domain) + fs_manage_nfs_symlinks(svirt_sandbox_domain) + fs_mount_nfs(svirt_sandbox_domain) + fs_unmount_nfs(svirt_sandbox_domain) + fs_exec_nfs_files(svirt_sandbox_domain) + kernel_rw_fs_sysctls(svirt_sandbox_domain) +') + +tunable_policy(`virt_use_samba',` + fs_manage_cifs_files(svirt_sandbox_domain) + fs_manage_cifs_dirs(svirt_sandbox_domain) + fs_manage_cifs_named_sockets(svirt_sandbox_domain) + fs_manage_cifs_symlinks(svirt_sandbox_domain) + fs_exec_cifs_files(svirt_sandbox_domain) +') + +tunable_policy(`virt_sandbox_use_fusefs',` + fs_manage_fusefs_dirs(svirt_sandbox_domain) + fs_manage_fusefs_files(svirt_sandbox_domain) + fs_manage_fusefs_symlinks(svirt_sandbox_domain) + fs_mount_fusefs(svirt_sandbox_domain) + fs_unmount_fusefs(svirt_sandbox_domain) + fs_exec_fusefs_files(svirt_sandbox_domain) +') + +optional_policy(` +tunable_policy(`virt_sandbox_share_apache_content',` + apache_exec_modules(svirt_sandbox_domain) + apache_read_sys_content(svirt_sandbox_domain) + ') +') + +optional_policy(` + container_read_share_files(svirt_sandbox_domain) + container_exec_share_files(svirt_sandbox_domain) + container_lib_filetrans(svirt_sandbox_domain,container_file_t, sock_file) + container_use_ptys(svirt_sandbox_domain) + container_spc_stream_connect(svirt_sandbox_domain) + fs_dontaudit_remount_tmpfs(svirt_sandbox_domain) + dev_dontaudit_mounton_sysfs(svirt_sandbox_domain) +') + +optional_policy(` + mta_dontaudit_read_spool_symlinks(svirt_sandbox_domain) +') + +optional_policy(` + ssh_use_ptys(svirt_sandbox_domain) +') + +optional_policy(` + udev_read_pid_files(svirt_sandbox_domain) +') + +optional_policy(` + userhelper_dontaudit_write_config(svirt_sandbox_domain) +') + +######################################## +# +# container_t local policy +# +virt_sandbox_domain_template(container) +typealias container_t alias svirt_lxc_net_t; +# Policy moved to container-selinux policy package + +######################################## +# +# container_t local policy +# +virt_sandbox_domain_template(svirt_qemu_net) +typeattribute svirt_qemu_net_t sandbox_net_domain; + +allow svirt_qemu_net_t self:capability { chown dac_read_search fowner fsetid ipc_lock kill setgid setpcap setuid sys_admin sys_boot sys_chroot sys_nice sys_ptrace sys_resource }; +dontaudit svirt_qemu_net_t self:capability2 block_suspend; +allow svirt_qemu_net_t self:process { execmem execstack }; + +tunable_policy(`virt_sandbox_use_netlink',` + allow svirt_qemu_net_t self:netlink_socket create_socket_perms; + allow svirt_qemu_net_t self:netlink_tcpdiag_socket create_netlink_socket_perms; + allow svirt_qemu_net_t self:netlink_kobject_uevent_socket create_socket_perms; +') + +manage_dirs_pattern(sandbox_net_domain, svirt_home_t, svirt_home_t) +manage_files_pattern(sandbox_net_domain, svirt_home_t, svirt_home_t) +manage_fifo_files_pattern(sandbox_net_domain, svirt_home_t, svirt_home_t) +manage_lnk_files_pattern(sandbox_net_domain, svirt_home_t, svirt_home_t) +manage_sock_files_pattern(sandbox_net_domain, svirt_home_t, svirt_home_t) +filetrans_pattern(sandbox_net_domain, virt_home_t, svirt_home_t, { dir sock_file file }) + +term_use_generic_ptys(svirt_qemu_net_t) +term_use_ptmx(svirt_qemu_net_t) + +dev_rw_kvm(svirt_qemu_net_t) + +manage_sock_files_pattern(svirt_qemu_net_t, qemu_var_run_t, qemu_var_run_t) + +list_dirs_pattern(svirt_qemu_net_t, virt_content_t, virt_content_t) +read_files_pattern(svirt_qemu_net_t, virt_content_t, virt_content_t) + +append_files_pattern(svirt_qemu_net_t, virt_log_t, virt_log_t) + +kernel_read_irq_sysctls(svirt_qemu_net_t) + +dev_read_sysfs(svirt_qemu_net_t) +dev_getattr_mtrr_dev(svirt_qemu_net_t) +dev_read_rand(svirt_qemu_net_t) +dev_read_urand(svirt_qemu_net_t) + +files_read_kernel_modules(svirt_qemu_net_t) + +fs_noxattr_type(container_file_t) +fs_mount_cgroup(svirt_qemu_net_t) +fs_manage_cgroup_dirs(svirt_qemu_net_t) +fs_manage_cgroup_files(svirt_qemu_net_t) + +term_pty(container_file_t) + +auth_use_nsswitch(svirt_qemu_net_t) + +rpm_read_db(svirt_qemu_net_t) + +logging_send_syslog_msg(svirt_qemu_net_t) + +userdom_use_user_ptys(svirt_qemu_net_t) + +tunable_policy(`virt_sandbox_use_audit',` + logging_send_audit_msgs(svirt_qemu_net_t) +') + +####################################### +# +# virtinterfaced local policy +# +allow virtinterfaced_t self:tcp_socket create_stream_socket_perms; + +manage_dirs_pattern(virtinterfaced_t, virt_var_lib_t, virt_var_lib_t) +manage_files_pattern(virtinterfaced_t, virt_var_lib_t, virt_var_lib_t) +manage_sock_files_pattern(virtinterfaced_t, virt_var_lib_t, virt_var_lib_t) +files_var_lib_filetrans(virtinterfaced_t, virt_var_lib_t, { dir file }) + +kernel_read_network_state(virtinterfaced_t) + +corecmd_exec_bin(virtinterfaced_t) + +fs_getattr_all_fs(virtinterfaced_t) + +modutils_read_module_config(virtinterfaced_t) + +sysnet_manage_config(virtinterfaced_t) + +userdom_read_all_users_state(virtinterfaced_t) + +####################################### +# +# virtnetworkd local policy +# +allow virtnetworkd_t self:capability { kill sys_ptrace }; +allow virtnetworkd_t self:netlink_netfilter_socket create_socket_perms; +allow virtnetworkd_t self:process setcap; +allow virtnetworkd_t self:tun_socket { create relabelfrom relabelto }; + +manage_lnk_files_pattern(virtnetworkd_t, virt_etc_rw_t, virt_etc_rw_t) + +manage_dirs_pattern(virtnetworkd_t, virt_var_lib_t, virt_var_lib_t) +manage_files_pattern(virtnetworkd_t, virt_var_lib_t, virt_var_lib_t) + +kernel_read_network_state(virtnetworkd_t) +kernel_request_load_module(virtnetworkd_t) +kernel_rw_net_sysctls(virtnetworkd_t) + +corenet_rw_tun_tap_dev(virtnetworkd_t) + +dev_rw_sysfs(virtnetworkd_t) + +sysnet_read_config(virtnetworkd_t) + +optional_policy(` + dnsmasq_domtrans(virtnetworkd_t) + dnsmasq_manage_pid_files(virtnetworkd_t) + dnsmasq_read_state(virtnetworkd_t) + dnsmasq_signal(virtnetworkd_t) + dnsmasq_signull(virtnetworkd_t) +') + +optional_policy(` + iptables_domtrans(virtnetworkd_t) + iptables_read_var_run(virtnetworkd_t) +') + +####################################### +# +# virtnodedevd local policy +# +allow virtnodedevd_t self:capability sys_admin; +allow virtnodedevd_t self:netlink_generic_socket create_socket_perms; + +kernel_request_load_module(virtnodedevd_t) + +dev_rw_mtrr(virtnodedevd_t) + +miscfiles_read_hwdata(virtnodedevd_t) + +optional_policy(` + udev_read_pid_files(virtnodedevd_t) +') + +####################################### +# +# virtnwfilterd local policy +# +allow virtnwfilterd_t self:capability net_raw; +allow virtnwfilterd_t self:netlink_netfilter_socket create_socket_perms; +allow virtnwfilterd_t self:netlink_rdma_socket create_socket_perms; +allow virtnwfilterd_t self:packet_socket { bind create getopt ioctl map setopt }; +allow virtnwfilterd_t self:rawip_socket create_socket_perms; + +manage_dirs_pattern(virtnwfilterd_t, virtnetworkd_var_run_t, virtnetworkd_var_run_t) +manage_files_pattern(virtnwfilterd_t, virtnetworkd_var_run_t, virtnetworkd_var_run_t) + +manage_files_pattern(virtnwfilterd_t, virt_var_run_t, virtlogd_var_run_t) + +kernel_read_all_proc(virtnwfilterd_t) +kernel_read_net_sysctls(virtnwfilterd_t) +kernel_request_load_module(virtnwfilterd_t) + +corecmd_exec_bin(virtnwfilterd_t) + +optional_policy(` + dnsmasq_domtrans(virtnwfilterd_t) + dnsmasq_manage_pid_files(virtnwfilterd_t) +') + +optional_policy(` + iptables_domtrans(virtnwfilterd_t) + iptables_filetrans_named_content(virtnwfilterd_t) + iptables_read_var_run(virtnwfilterd_t) +') + +####################################### +# +# virtproxyd local policy +# +allow virtproxyd_t self:tcp_socket create_stream_socket_perms; +allow virtproxyd_t self:udp_socket create_socket_perms; + +corenet_tcp_bind_generic_node(virtproxyd_t) +corenet_tcp_bind_virt_port(virtproxyd_t) + +userdom_read_all_users_state(virtproxyd_t) + +####################################### +# +# virtqemud local policy +# +allow virtqemud_t self:bpf { map_create map_read map_write prog_load prog_run }; +allow virtqemud_t self:capability { audit_write chown dac_override dac_read_search fowner fsetid kill setgid setuid sys_admin sys_chroot sys_ptrace sys_rawio }; +allow virtqemud_t self:netlink_audit_socket nlmsg_relay; +allow virtqemud_t self:process { setcap setexec setrlimit setsockcreate }; +allow virtqemud_t self:tcp_socket create_socket_perms; +allow virtqemud_t self:tun_socket create; +allow virtqemud_t self:udp_socket { create getattr }; + +allow virtqemud_t svirt_t:process { setsched signal signull transition }; +allow virtqemud_t svirt_t:unix_stream_socket { connectto create_stream_socket_perms }; +allow virtqemud_t svirt_socket_t:unix_stream_socket connectto; + +allow virtqemud_t qemu_var_run_t:dir relabelfrom; + +allow virtqemud_t virt_cache_t:file { relabelfrom relabelto }; + +allow virtqemud_t virt_driver_domain:unix_stream_socket connectto; + +allow virtqemud_t virt_var_run_t:file map; + +allow virtqemud_t virtlogd_t:fifo_file rw_inherited_fifo_file_perms; +allow virtqemud_t virtlogd_t:unix_stream_socket connectto; + +manage_dirs_pattern(virtqemud_t, virtqemud_tmp_t, virtqemud_tmp_t) +manage_files_pattern(virtqemud_t, virtqemud_tmp_t, virtqemud_tmp_t) +manage_sock_files_pattern(virtqemud_t, virtqemud_tmp_t, virtqemud_tmp_t) +files_tmp_filetrans(virtqemud_t, virtqemud_tmp_t, { file dir sock_file}) + +manage_dirs_pattern(virtqemud_t, qemu_var_run_t, qemu_var_run_t) +manage_files_pattern(virtqemud_t, qemu_var_run_t, qemu_var_run_t) +manage_sock_files_pattern(virtqemud_t, qemu_var_run_t, qemu_var_run_t) + +manage_dirs_pattern(virtqemud_t, svirt_image_t, svirt_image_t) +manage_files_pattern(virtqemud_t, svirt_image_t, svirt_image_t) +manage_sock_files_pattern(virtqemud_t, svirt_image_t, svirt_image_t) +read_files_pattern(virtqemud_t, svirt_t, svirt_t) +read_lnk_files_pattern(virtqemud_t, svirt_t, svirt_t) + +manage_files_pattern(virtqemud_t, virt_content_t, virt_content_t) + +manage_files_pattern(virtqemud_t, virt_image_t, virt_image_t) + +manage_dirs_pattern(virtqemud_t, virt_var_lib_t, virt_var_lib_t) +manage_files_pattern(virtqemud_t, virt_var_lib_t, virt_var_lib_t) + +manage_sock_files_pattern(virtqemud_t, virt_var_run_t, virt_var_run_t) + +manage_sock_files_pattern(virtqemud_t, virtlogd_var_run_t, virtlogd_var_run_t) + +read_files_pattern(virtqemud_t, virtproxyd_t, virtproxyd_t) + +kernel_read_all_proc(virtqemud_t) +kernel_request_load_module(virtqemud_t) + +corecmd_exec_bin(virtqemud_t) +corecmd_exec_shell(virtqemud_t) + +corenet_rw_tun_tap_dev(virtqemud_t) +corenet_tcp_bind_generic_node(virtqemud_t) +corenet_tcp_bind_vnc_port(virtqemud_t) + +dev_read_cpuid(virtqemud_t) +dev_read_sysfs(virtqemud_t) +dev_read_urand(virtqemud_t) +dev_relabel_all_dev_nodes(virtqemud_t) +dev_rw_kvm(virtqemud_t) +dev_rw_vhost(virtqemud_t) + +files_mounton_non_security(virtqemud_t) +files_read_all_symlinks(virtqemud_t) + +fs_getattr_hugetlbfs(virtqemud_t) +fs_manage_hugetlbfs_dirs(virtqemud_t) +fs_manage_cgroup_dirs(virtqemud_t) +fs_manage_cgroup_files(virtqemud_t) +fs_manage_tmpfs_chr_files(virtqemud_t) +fs_manage_tmpfs_dirs(virtqemud_t) +fs_manage_tmpfs_symlinks(virtqemud_t) +fs_mount_tmpfs(virtqemud_t) +fs_read_nsfs_files(virtqemud_t) +fs_relabel_tmpfs_chr_file(virtqemud_t) + +seutil_read_default_contexts(virtqemud_t) +seutil_read_file_contexts(virtqemud_t) + +init_stream_connect(virtqemud_t) +init_stream_connect_script(virtqemud_t) + +sysnet_exec_ifconfig(virtqemud_t) +sysnet_manage_config(virtqemud_t) + +userdom_read_all_users_state(virtqemud_t) +userdom_read_user_home_content_files(virtqemud_t) +userdom_relabel_user_home_files(virtqemud_t) + +tunable_policy(`virtqemud_use_execmem',` + allow virtqemud_t self:process { execmem execstack }; +') + +optional_policy(` + dmidecode_domtrans(virtqemud_t) +') + +optional_policy(` + qemu_exec(virtqemud_t) +') + +optional_policy(` + systemd_userdbd_stream_connect(virtqemud_t) +') + +####################################### +# +# virtstoraged local policy +# +allow virtstoraged_t self:capability { dac_override dac_read_search ipc_lock }; + +files_tmp_filetrans(virtstoraged_t, virtstoraged_tmp_t, { file dir }) + +manage_lnk_files_pattern(virtstoraged_t, virt_etc_rw_t, virt_etc_rw_t) + +manage_files_pattern(virtstoraged_t, virt_image_t, virt_image_t) + +manage_files_pattern(virtstoraged_t, svirt_image_t, svirt_image_t) + +manage_dirs_pattern(virtstoraged_t, virt_var_lib_t, virt_var_lib_t) +manage_files_pattern(virtstoraged_t, virt_var_lib_t, virt_var_lib_t) + +corecmd_exec_bin(virtstoraged_t) + +fs_getattr_all_fs(virtstoraged_t) + +userdom_read_user_home_content_files(virtstoraged_t) + +####################################### +# +# virtvboxd local policy +# +allow virtvboxd_t self:netlink_audit_socket create; +allow virtvboxd_t self:netlink_kobject_uevent_socket create_socket_perms; +allow virtvboxd_t self:netlink_route_socket create_socket_perms; +allow virtvboxd_t self:unix_dgram_socket create; +allow virtvboxd_t virt_etc_t:dir search; + +####################################### +# +# virtvzd local policy +# +# Use unconfined_domain macro until the policy for this driver is made, +# to avoid lots of SELinux policy denials and confused users. +optional_policy(` + unconfined_domain(virtvzd_t) +') + +####################################### +# +# virtxend local policy +# +# Use unconfined_domain macro until the policy for this driver is made, +# to avoid lots of SELinux policy denials and confused users. +optional_policy(` + unconfined_domain(virtxend_t) +') + +####################################### +# +# tye for svirt sockets +# + +type svirt_socket_t; +domain_type(svirt_socket_t) +role system_r types svirt_socket_t; +allow virtd_t svirt_socket_t:unix_stream_socket { connectto create_stream_socket_perms }; +allow virt_domain svirt_socket_t:unix_stream_socket { connectto create_stream_socket_perms }; + +tunable_policy(`virt_transition_userdomain',` + userdom_transition(virtd_t) + userdom_transition(virtd_lxc_t) +') + +######################################## +# +# svirt_kvm_net_t local policy +# +virt_sandbox_domain_template(svirt_kvm_net) +typeattribute svirt_kvm_net_t sandbox_net_domain; + +allow svirt_kvm_net_t self:capability { chown dac_read_search fowner fsetid ipc_lock kill setgid setpcap setuid sys_admin sys_boot sys_chroot sys_nice sys_ptrace sys_resource }; +dontaudit svirt_kvm_net_t self:capability2 block_suspend; + +tunable_policy(`virt_sandbox_use_netlink',` + allow svirt_kvm_net_t self:netlink_socket create_socket_perms; + allow svirt_kvm_net_t self:netlink_tcpdiag_socket create_netlink_socket_perms; + allow svirt_kvm_net_t self:netlink_kobject_uevent_socket create_socket_perms; +') + +term_use_generic_ptys(svirt_kvm_net_t) +term_use_ptmx(svirt_kvm_net_t) + +dev_rw_kvm(svirt_kvm_net_t) + +manage_sock_files_pattern(svirt_kvm_net_t, virt_var_run_t, virt_var_run_t) + +list_dirs_pattern(svirt_kvm_net_t, virt_content_t, virt_content_t) +read_files_pattern(svirt_kvm_net_t, virt_content_t, virt_content_t) + +append_files_pattern(svirt_kvm_net_t, virt_log_t, virt_log_t) + +kernel_read_network_state(svirt_kvm_net_t) +kernel_read_irq_sysctls(svirt_kvm_net_t) + +dev_read_sysfs(svirt_kvm_net_t) +dev_getattr_mtrr_dev(svirt_kvm_net_t) +dev_read_rand(svirt_kvm_net_t) +dev_read_urand(svirt_kvm_net_t) + +files_read_kernel_modules(svirt_kvm_net_t) + +fs_noxattr_type(container_file_t) +fs_mount_cgroup(svirt_kvm_net_t) +fs_manage_cgroup_dirs(svirt_kvm_net_t) +fs_manage_cgroup_files(svirt_kvm_net_t) + +term_pty(container_file_t) + +auth_use_nsswitch(svirt_kvm_net_t) + +rpm_read_db(svirt_kvm_net_t) + +logging_send_syslog_msg(svirt_kvm_net_t) + +tunable_policy(`virt_sandbox_use_audit',` + logging_send_audit_msgs(svirt_kvm_net_t) +') + +userdom_use_user_ptys(svirt_kvm_net_t) + +kernel_read_network_state(sandbox_net_domain) + +allow sandbox_net_domain self:capability { net_admin net_bind_service net_raw }; +allow sandbox_net_domain self:cap_userns { net_admin net_bind_service net_raw }; + +allow sandbox_net_domain self:udp_socket create_socket_perms; +allow sandbox_net_domain self:tcp_socket create_stream_socket_perms; +allow sandbox_net_domain self:netlink_route_socket create_netlink_socket_perms; +allow sandbox_net_domain self:packet_socket create_socket_perms; +allow sandbox_net_domain self:socket create_socket_perms; +allow sandbox_net_domain self:rawip_socket create_stream_socket_perms; +allow sandbox_net_domain self:netlink_kobject_uevent_socket create_socket_perms; + +corenet_tcp_bind_generic_node(sandbox_net_domain) +corenet_udp_bind_generic_node(sandbox_net_domain) +corenet_raw_bind_generic_node(sandbox_net_domain) +corenet_tcp_sendrecv_all_ports(sandbox_net_domain) +corenet_udp_sendrecv_all_ports(sandbox_net_domain) +corenet_udp_bind_all_ports(sandbox_net_domain) +corenet_tcp_bind_all_ports(sandbox_net_domain) +corenet_tcp_connect_all_ports(sandbox_net_domain) + +optional_policy(` + sssd_stream_connect(sandbox_net_domain) +') + +optional_policy(` + systemd_dbus_chat_logind(sandbox_net_domain) +') + +allow sandbox_caps_domain self:capability { audit_write chown dac_read_search fowner kill mknod net_bind_service net_raw setfcap setgid setpcap setuid sys_chroot }; +allow sandbox_caps_domain self:cap_userns { audit_write chown dac_read_search fowner kill mknod net_bind_service net_raw setfcap setgid setpcap setuid sys_chroot }; + +list_dirs_pattern(svirt_sandbox_domain, container_ro_file_t, container_ro_file_t) +read_files_pattern(svirt_sandbox_domain, container_ro_file_t, container_ro_file_t) +read_lnk_files_pattern(svirt_sandbox_domain, container_ro_file_t, container_ro_file_t) +allow svirt_sandbox_domain container_ro_file_t:file execmod; +can_exec(svirt_sandbox_domain, container_ro_file_t) -- 2.31.1

On Fri, Aug 06, 2021 at 06:47:58PM +0100, Daniel P. Berrangé wrote:
From: Nikola Knazekova <nknazeko@redhat.com>
SELinux policy was created for:
Hypervisor drivers: - virtqemud (QEMU/KVM) - virtlxcd (LXC) - virtvboxd (VirtualBox)
Secondary drivers: - virtstoraged (host storage mgmt) - virtnetworkd (virtual network mgmt) - virtinterface (network interface mgmt) - virtnodedevd (physical device mgmt) - virtsecretd (security credential mgmt) - virtnwfilterd (ip[6]tables/ebtables mgmt) - virtproxyd (proxy daemon)
SELinux policy for virtvxz and virtxend has not been created yet, because I wasn't able to reproduce AVC messages. These drivers run in unconfined_domain until the AVC messages are reproduced internally and policy for these drivers is made.
Signed-off-by: Nikola Knazekova <nknazeko@redhat.com> --- src/security/selinux/virt.fc | 111 ++ src/security/selinux/virt.if | 1984 ++++++++++++++++++++++++++++++++ src/security/selinux/virt.te | 2078 ++++++++++++++++++++++++++++++++++ 3 files changed, 4173 insertions(+) create mode 100644 src/security/selinux/virt.fc create mode 100644 src/security/selinux/virt.if create mode 100644 src/security/selinux/virt.te
diff --git a/src/security/selinux/virt.fc b/src/security/selinux/virt.fc new file mode 100644 index 0000000000..554e1094d9 --- /dev/null +++ b/src/security/selinux/virt.fc @@ -0,0 +1,111 @@ +HOME_DIR/\.libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.cache/libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.cache/libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.config/libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.config/libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/VirtualMachines(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/VirtualMachines/isos(/.*)? gen_context(system_u:object_r:virt_content_t,s0)
These two doesn't look like libvirt selinux bits, more like virt-manager or some other tool.
+HOME_DIR/\.local/share/libvirt/images(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.local/share/libvirt/boot(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) + +/etc/libvirt -d gen_context(system_u:object_r:virt_etc_t,s0) +/etc/libvirt/virtlogd\.conf -- gen_context(system_u:object_r:virtlogd_etc_t,s0) +/etc/libvirt/[^/]* -- gen_context(system_u:object_r:virt_etc_t,s0) +/etc/libvirt/[^/]* -d gen_context(system_u:object_r:virt_etc_rw_t,s0) +/etc/libvirt/.*/.* gen_context(system_u:object_r:virt_etc_rw_t,s0) +/etc/rc\.d/init\.d/libvirtd -- gen_context(system_u:object_r:virtd_initrc_exec_t,s0) +/etc/rc\.d/init\.d/virtlogd -- gen_context(system_u:object_r:virtlogd_initrc_exec_t,s0) + +/usr/libexec/libvirt_lxc -- gen_context(system_u:object_r:virtd_lxc_exec_t,s0) + +/usr/sbin/libvirtd -- gen_context(system_u:object_r:virtd_exec_t,s0) +/usr/sbin/virtlockd -- gen_context(system_u:object_r:virtlogd_exec_t,s0) +/usr/sbin/virtlogd -- gen_context(system_u:object_r:virtlogd_exec_t,s0) +/usr/bin/virsh -- gen_context(system_u:object_r:virsh_exec_t,s0) + +/usr/sbin/virtinterfaced -- gen_context(system_u:object_r:virtinterfaced_exec_t,s0) +/usr/sbin/virtlxcd -- gen_context(system_u:object_r:virtd_lxc_exec_t,s0) +/usr/sbin/virtnetworkd -- gen_context(system_u:object_r:virtnetworkd_exec_t,s0) +/usr/sbin/virtnodedevd -- gen_context(system_u:object_r:virtnodedevd_exec_t,s0) +/usr/sbin/virtnwfilterd -- gen_context(system_u:object_r:virtnwfilterd_exec_t,s0) +/usr/sbin/virtproxyd -- gen_context(system_u:object_r:virtproxyd_exec_t,s0) +/usr/sbin/virtqemud -- gen_context(system_u:object_r:virtqemud_exec_t,s0) +/usr/sbin/virtsecretd -- gen_context(system_u:object_r:virtsecretd_exec_t,s0) +/usr/sbin/virtstoraged -- gen_context(system_u:object_r:virtstoraged_exec_t,s0) +/usr/sbin/virtvboxd -- gen_context(system_u:object_r:virtvboxd_exec_t,s0) +/usr/sbin/virtvzd -- gen_context(system_u:object_r:virtvzd_exec_t,s0) +/usr/sbin/virtxend -- gen_context(system_u:object_r:virtxend_exec_t,s0) + +/var/cache/libvirt(/.*)? gen_context(system_u:object_r:virt_cache_t,s0-mls_systemhigh) + +/var/lib/libvirt(/.*)? gen_context(system_u:object_r:virt_var_lib_t,s0) +/var/lib/libvirt/boot(/.*)? gen_context(system_u:object_r:virt_content_t,s0) +/var/lib/libvirt/images(/.*)? gen_context(system_u:object_r:virt_image_t,s0) +/var/lib/libvirt/isos(/.*)? gen_context(system_u:object_r:virt_content_t,s0) +/var/lib/libvirt/lockd(/.*)? gen_context(system_u:object_r:virt_var_lockd_t,s0) +/var/lib/libvirt/qemu(/.*)? gen_context(system_u:object_r:qemu_var_run_t,s0-mls_systemhigh) + +/var/log/log(/.*)? gen_context(system_u:object_r:virt_log_t,s0)
Based on commit from selinux-policy 63ead48cf8 this seems vdsm related. I don't think that we use this directory in libvirt.
+/var/log/libvirt(/.*)? gen_context(system_u:object_r:virt_log_t,s0) +/var/run/libvirtd\.pid -- gen_context(system_u:object_r:virt_var_run_t,s0) +# Avoid calling m4's "interface" by using en empty string +/var/run/libvirt/interfac(e)(/.*)? gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/libvirt/nodedev(/.*)? gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/libvirt/nwfilter(/.*)? gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/libvirt/secrets(/.*)? gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/libvirt/storage(/.*)? gen_context(system_u:object_r:virtstoraged_var_run_t,s0) + +/var/run/virtlogd\.pid -- gen_context(system_u:object_r:virtlogd_var_run_t,s0) +/var/run/virtlxcd\.pid -- gen_context(system_u:object_r:virt_lxc_var_run_t,s0) +/var/run/virtqemud\.pid -- gen_context(system_u:object_r:virtqemud_var_run_t,s0) +/var/run/virtvboxd\.pid -- gen_context(system_u:object_r:virtvboxd_var_run_t,s0) +/var/run/virtproxyd\.pid -- gen_context(system_u:object_r:virtproxyd_var_run_t,s0) +/var/run/virtinterfaced\.pid -- gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/virtnetworkd\.pid -- gen_context(system_u:object_r:virtnetworkd_var_run_t,s0) +/var/run/virtnodedevd\.pid -- gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/virtnwfilterd\.pid -- gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/virtnwfilterd-binding\.pid -- gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/virtsecretd\.pid -- gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/virtstoraged\.pid -- gen_context(system_u:object_r:virtstoraged_var_run_t,s0)
[...] I was not able to figure out on which selinux policy is this one based on as the upstream for rawhide from <https://github.com/fedora-selinux/selinux-policy.git> is a bit different. There are some cosmetics changes but I see two major differences: - the upstream policy doesn't have split-daemon bits compared to this one, I checked it and it looks reasonable but I'm not that familiar with selinux policy - the upstream policy has important `system.token` issue fix that we've seen recently introduced by upstream commit <1f761d0bbd> Pavel

On Tue, Aug 10, 2021 at 10:39:23AM +0200, Pavel Hrdina wrote:
On Fri, Aug 06, 2021 at 06:47:58PM +0100, Daniel P. Berrangé wrote:
From: Nikola Knazekova <nknazeko@redhat.com>
SELinux policy was created for:
Hypervisor drivers: - virtqemud (QEMU/KVM) - virtlxcd (LXC) - virtvboxd (VirtualBox)
Secondary drivers: - virtstoraged (host storage mgmt) - virtnetworkd (virtual network mgmt) - virtinterface (network interface mgmt) - virtnodedevd (physical device mgmt) - virtsecretd (security credential mgmt) - virtnwfilterd (ip[6]tables/ebtables mgmt) - virtproxyd (proxy daemon)
SELinux policy for virtvxz and virtxend has not been created yet, because I wasn't able to reproduce AVC messages. These drivers run in unconfined_domain until the AVC messages are reproduced internally and policy for these drivers is made.
Signed-off-by: Nikola Knazekova <nknazeko@redhat.com> --- src/security/selinux/virt.fc | 111 ++ src/security/selinux/virt.if | 1984 ++++++++++++++++++++++++++++++++ src/security/selinux/virt.te | 2078 ++++++++++++++++++++++++++++++++++ 3 files changed, 4173 insertions(+) create mode 100644 src/security/selinux/virt.fc create mode 100644 src/security/selinux/virt.if create mode 100644 src/security/selinux/virt.te
diff --git a/src/security/selinux/virt.fc b/src/security/selinux/virt.fc new file mode 100644 index 0000000000..554e1094d9 --- /dev/null +++ b/src/security/selinux/virt.fc @@ -0,0 +1,111 @@ +HOME_DIR/\.libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.cache/libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.cache/libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.config/libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.config/libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/VirtualMachines(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/VirtualMachines/isos(/.*)? gen_context(system_u:object_r:virt_content_t,s0)
These two doesn't look like libvirt selinux bits, more like virt-manager or some other tool.
Rationale is largely lost in the mists of time to be honest. $HOME/VirtualMachines does make sense for desktop virt use case I think, while the below rules make sense as a direct translation of libvirt's system paths. I think its ok to have both really
+HOME_DIR/\.local/share/libvirt/images(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.local/share/libvirt/boot(/.*)? gen_context(system_u:object_r:svirt_home_t,s0)
+/var/lib/libvirt(/.*)? gen_context(system_u:object_r:virt_var_lib_t,s0) +/var/lib/libvirt/boot(/.*)? gen_context(system_u:object_r:virt_content_t,s0) +/var/lib/libvirt/images(/.*)? gen_context(system_u:object_r:virt_image_t,s0) +/var/lib/libvirt/isos(/.*)? gen_context(system_u:object_r:virt_content_t,s0) +/var/lib/libvirt/lockd(/.*)? gen_context(system_u:object_r:virt_var_lockd_t,s0) +/var/lib/libvirt/qemu(/.*)? gen_context(system_u:object_r:qemu_var_run_t,s0-mls_systemhigh) + +/var/log/log(/.*)? gen_context(system_u:object_r:virt_log_t,s0)
Based on commit from selinux-policy 63ead48cf8 this seems vdsm related. I don't think that we use this directory in libvirt.
Yeah, that's dubious.
+/var/log/libvirt(/.*)? gen_context(system_u:object_r:virt_log_t,s0) +/var/run/libvirtd\.pid -- gen_context(system_u:object_r:virt_var_run_t,s0) +# Avoid calling m4's "interface" by using en empty string +/var/run/libvirt/interfac(e)(/.*)? gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/libvirt/nodedev(/.*)? gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/libvirt/nwfilter(/.*)? gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/libvirt/secrets(/.*)? gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/libvirt/storage(/.*)? gen_context(system_u:object_r:virtstoraged_var_run_t,s0) + +/var/run/virtlogd\.pid -- gen_context(system_u:object_r:virtlogd_var_run_t,s0) +/var/run/virtlxcd\.pid -- gen_context(system_u:object_r:virt_lxc_var_run_t,s0) +/var/run/virtqemud\.pid -- gen_context(system_u:object_r:virtqemud_var_run_t,s0) +/var/run/virtvboxd\.pid -- gen_context(system_u:object_r:virtvboxd_var_run_t,s0) +/var/run/virtproxyd\.pid -- gen_context(system_u:object_r:virtproxyd_var_run_t,s0) +/var/run/virtinterfaced\.pid -- gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/virtnetworkd\.pid -- gen_context(system_u:object_r:virtnetworkd_var_run_t,s0) +/var/run/virtnodedevd\.pid -- gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/virtnwfilterd\.pid -- gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/virtnwfilterd-binding\.pid -- gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/virtsecretd\.pid -- gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/virtstoraged\.pid -- gen_context(system_u:object_r:virtstoraged_var_run_t,s0)
[...]
I was not able to figure out on which selinux policy is this one based on as the upstream for rawhide from <https://github.com/fedora-selinux/selinux-policy.git> is a bit different. There are some cosmetics changes but I see two major differences:
- the upstream policy doesn't have split-daemon bits compared to this one, I checked it and it looks reasonable but I'm not that familiar with selinux policy
Now I compare the two, I see there's a bunch of stuff in the current fedora virt.te that doesn't exist in this virt.te. So if we deploy this, then its likely to break stuff that's in the current virt.te that we've omitted. I should have checked this more closely before re-sendig, as I just blindly assumed that the differences to fedora-selinux had been eliminated after my original review comments :-(
- the upstream policy has important `system.token` issue fix that we've seen recently introduced by upstream commit <1f761d0bbd>
My view for pulling any SElinux policy into libvirt.git is that we need to untangle the current fedora selinux virt policy first to remove all the non-libvirt pieces. It should then be a direct copy into libvirt.git with no modifications. So I don't think this is mergable as it exists now. 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 :|

On 10. 08. 21 18:35, Daniel P. Berrangé wrote:
On Tue, Aug 10, 2021 at 10:39:23AM +0200, Pavel Hrdina wrote:
On Fri, Aug 06, 2021 at 06:47:58PM +0100, Daniel P. Berrangé wrote:
From: Nikola Knazekova <nknazeko@redhat.com>
SELinux policy was created for:
Hypervisor drivers: - virtqemud (QEMU/KVM) - virtlxcd (LXC) - virtvboxd (VirtualBox)
Secondary drivers: - virtstoraged (host storage mgmt) - virtnetworkd (virtual network mgmt) - virtinterface (network interface mgmt) - virtnodedevd (physical device mgmt) - virtsecretd (security credential mgmt) - virtnwfilterd (ip[6]tables/ebtables mgmt) - virtproxyd (proxy daemon)
SELinux policy for virtvxz and virtxend has not been created yet, because I wasn't able to reproduce AVC messages. These drivers run in unconfined_domain until the AVC messages are reproduced internally and policy for these drivers is made.
Signed-off-by: Nikola Knazekova <nknazeko@redhat.com> --- src/security/selinux/virt.fc | 111 ++ src/security/selinux/virt.if | 1984 ++++++++++++++++++++++++++++++++ src/security/selinux/virt.te | 2078 ++++++++++++++++++++++++++++++++++ 3 files changed, 4173 insertions(+) create mode 100644 src/security/selinux/virt.fc create mode 100644 src/security/selinux/virt.if create mode 100644 src/security/selinux/virt.te
diff --git a/src/security/selinux/virt.fc b/src/security/selinux/virt.fc new file mode 100644 index 0000000000..554e1094d9 --- /dev/null +++ b/src/security/selinux/virt.fc @@ -0,0 +1,111 @@ +HOME_DIR/\.libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.cache/libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.cache/libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.config/libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.config/libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/VirtualMachines(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/VirtualMachines/isos(/.*)? gen_context(system_u:object_r:virt_content_t,s0) These two doesn't look like libvirt selinux bits, more like virt-manager or some other tool. Rationale is largely lost in the mists of time to be honest. $HOME/VirtualMachines does make sense for desktop virt use case I think, while the below rules make sense as a direct translation of libvirt's system paths.
I think its ok to have both really
+HOME_DIR/\.local/share/libvirt/images(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.local/share/libvirt/boot(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +/var/lib/libvirt(/.*)? gen_context(system_u:object_r:virt_var_lib_t,s0) +/var/lib/libvirt/boot(/.*)? gen_context(system_u:object_r:virt_content_t,s0) +/var/lib/libvirt/images(/.*)? gen_context(system_u:object_r:virt_image_t,s0) +/var/lib/libvirt/isos(/.*)? gen_context(system_u:object_r:virt_content_t,s0) +/var/lib/libvirt/lockd(/.*)? gen_context(system_u:object_r:virt_var_lockd_t,s0) +/var/lib/libvirt/qemu(/.*)? gen_context(system_u:object_r:qemu_var_run_t,s0-mls_systemhigh) + +/var/log/log(/.*)? gen_context(system_u:object_r:virt_log_t,s0) Based on commit from selinux-policy 63ead48cf8 this seems vdsm related. I don't think that we use this directory in libvirt. Yeah, that's dubious. Good point, we'll move it out of virt policy.
+/var/log/libvirt(/.*)? gen_context(system_u:object_r:virt_log_t,s0) +/var/run/libvirtd\.pid -- gen_context(system_u:object_r:virt_var_run_t,s0) +# Avoid calling m4's "interface" by using en empty string +/var/run/libvirt/interfac(e)(/.*)? gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/libvirt/nodedev(/.*)? gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/libvirt/nwfilter(/.*)? gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/libvirt/secrets(/.*)? gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/libvirt/storage(/.*)? gen_context(system_u:object_r:virtstoraged_var_run_t,s0) + +/var/run/virtlogd\.pid -- gen_context(system_u:object_r:virtlogd_var_run_t,s0) +/var/run/virtlxcd\.pid -- gen_context(system_u:object_r:virt_lxc_var_run_t,s0) +/var/run/virtqemud\.pid -- gen_context(system_u:object_r:virtqemud_var_run_t,s0) +/var/run/virtvboxd\.pid -- gen_context(system_u:object_r:virtvboxd_var_run_t,s0) +/var/run/virtproxyd\.pid -- gen_context(system_u:object_r:virtproxyd_var_run_t,s0) +/var/run/virtinterfaced\.pid -- gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/virtnetworkd\.pid -- gen_context(system_u:object_r:virtnetworkd_var_run_t,s0) +/var/run/virtnodedevd\.pid -- gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/virtnwfilterd\.pid -- gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/virtnwfilterd-binding\.pid -- gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/virtsecretd\.pid -- gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/virtstoraged\.pid -- gen_context(system_u:object_r:virtstoraged_var_run_t,s0) [...]
I was not able to figure out on which selinux policy is this one based on as the upstream for rawhide from <https://github.com/fedora-selinux/selinux-policy.git> is a bit different. There are some cosmetics changes but I see two major differences:
- the upstream policy doesn't have split-daemon bits compared to this one, I checked it and it looks reasonable but I'm not that familiar with selinux policy Now I compare the two, I see there's a bunch of stuff in the current fedora virt.te that doesn't exist in this virt.te.
This policy has been mostly rewritten by Nikola Knazekova to work with the split daemon configuration. It's only been tested using libvirt-tck and by running some VM by hand so we could use your help running other tests you have available. There has actually been some progress on the policy since I last updated the PR. The latest version is available here: https://github.com/5umm3r15/selinux-policy/blob/libvirt-selinux/policy/modul... https://github.com/5umm3r15/selinux-policy/blob/libvirt-selinux/policy/modul... https://github.com/5umm3r15/selinux-policy/blob/libvirt-selinux/policy/modul... The MLS parts of the policy are still not 100% since we are not sure about some access that is taking place during testing with libvirt-tck. Please see: https://gitlab.com/libvirt/libvirt-tck/-/merge_requests/8#note_601463944
So if we deploy this, then its likely to break stuff that's in the current virt.te that we've omitted.
I should have checked this more closely before re-sendig, as I just blindly assumed that the differences to fedora-selinux had been eliminated after my original review comments :-(
- the upstream policy has important `system.token` issue fix that we've seen recently introduced by upstream commit <1f761d0bbd>
My view for pulling any SElinux policy into libvirt.git is that we need to untangle the current fedora selinux virt policy first to remove all the non-libvirt pieces. It should then be a direct copy into libvirt.git with no modifications.
So I don't think this is mergable as it exists now.
The policy has been split to virt and virt_supplementary (https://github.com/5umm3r15/selinux-policy/blob/libvirt-selinux/policy/modul...), where virt_supplementary has the bits that are non-libvirt (this part will stay in selinux-policy repo). We may have overlooked some bits in the plit, so feel free to point them out. Regards, Vit
Regards, Daniel

On Thu, Aug 19, 2021 at 05:23:48PM +0200, Vit Mojzis wrote:
On 10. 08. 21 18:35, Daniel P. Berrangé wrote:
On Tue, Aug 10, 2021 at 10:39:23AM +0200, Pavel Hrdina wrote:
On Fri, Aug 06, 2021 at 06:47:58PM +0100, Daniel P. Berrangé wrote:
From: Nikola Knazekova <nknazeko@redhat.com>
SELinux policy was created for:
Hypervisor drivers: - virtqemud (QEMU/KVM) - virtlxcd (LXC) - virtvboxd (VirtualBox)
Secondary drivers: - virtstoraged (host storage mgmt) - virtnetworkd (virtual network mgmt) - virtinterface (network interface mgmt) - virtnodedevd (physical device mgmt) - virtsecretd (security credential mgmt) - virtnwfilterd (ip[6]tables/ebtables mgmt) - virtproxyd (proxy daemon)
SELinux policy for virtvxz and virtxend has not been created yet, because I wasn't able to reproduce AVC messages. These drivers run in unconfined_domain until the AVC messages are reproduced internally and policy for these drivers is made.
Signed-off-by: Nikola Knazekova <nknazeko@redhat.com> --- src/security/selinux/virt.fc | 111 ++ src/security/selinux/virt.if | 1984 ++++++++++++++++++++++++++++++++ src/security/selinux/virt.te | 2078 ++++++++++++++++++++++++++++++++++ 3 files changed, 4173 insertions(+) create mode 100644 src/security/selinux/virt.fc create mode 100644 src/security/selinux/virt.if create mode 100644 src/security/selinux/virt.te
diff --git a/src/security/selinux/virt.fc b/src/security/selinux/virt.fc new file mode 100644 index 0000000000..554e1094d9 --- /dev/null +++ b/src/security/selinux/virt.fc @@ -0,0 +1,111 @@ +HOME_DIR/\.libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.cache/libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.cache/libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.config/libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.config/libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/VirtualMachines(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/VirtualMachines/isos(/.*)? gen_context(system_u:object_r:virt_content_t,s0) These two doesn't look like libvirt selinux bits, more like virt-manager or some other tool. Rationale is largely lost in the mists of time to be honest. $HOME/VirtualMachines does make sense for desktop virt use case I think, while the below rules make sense as a direct translation of libvirt's system paths.
I think its ok to have both really
+HOME_DIR/\.local/share/libvirt/images(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.local/share/libvirt/boot(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +/var/lib/libvirt(/.*)? gen_context(system_u:object_r:virt_var_lib_t,s0) +/var/lib/libvirt/boot(/.*)? gen_context(system_u:object_r:virt_content_t,s0) +/var/lib/libvirt/images(/.*)? gen_context(system_u:object_r:virt_image_t,s0) +/var/lib/libvirt/isos(/.*)? gen_context(system_u:object_r:virt_content_t,s0) +/var/lib/libvirt/lockd(/.*)? gen_context(system_u:object_r:virt_var_lockd_t,s0) +/var/lib/libvirt/qemu(/.*)? gen_context(system_u:object_r:qemu_var_run_t,s0-mls_systemhigh) + +/var/log/log(/.*)? gen_context(system_u:object_r:virt_log_t,s0) Based on commit from selinux-policy 63ead48cf8 this seems vdsm related. I don't think that we use this directory in libvirt. Yeah, that's dubious. Good point, we'll move it out of virt policy.
+/var/log/libvirt(/.*)? gen_context(system_u:object_r:virt_log_t,s0) +/var/run/libvirtd\.pid -- gen_context(system_u:object_r:virt_var_run_t,s0) +# Avoid calling m4's "interface" by using en empty string +/var/run/libvirt/interfac(e)(/.*)? gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/libvirt/nodedev(/.*)? gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/libvirt/nwfilter(/.*)? gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/libvirt/secrets(/.*)? gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/libvirt/storage(/.*)? gen_context(system_u:object_r:virtstoraged_var_run_t,s0) + +/var/run/virtlogd\.pid -- gen_context(system_u:object_r:virtlogd_var_run_t,s0) +/var/run/virtlxcd\.pid -- gen_context(system_u:object_r:virt_lxc_var_run_t,s0) +/var/run/virtqemud\.pid -- gen_context(system_u:object_r:virtqemud_var_run_t,s0) +/var/run/virtvboxd\.pid -- gen_context(system_u:object_r:virtvboxd_var_run_t,s0) +/var/run/virtproxyd\.pid -- gen_context(system_u:object_r:virtproxyd_var_run_t,s0) +/var/run/virtinterfaced\.pid -- gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/virtnetworkd\.pid -- gen_context(system_u:object_r:virtnetworkd_var_run_t,s0) +/var/run/virtnodedevd\.pid -- gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/virtnwfilterd\.pid -- gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/virtnwfilterd-binding\.pid -- gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/virtsecretd\.pid -- gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/virtstoraged\.pid -- gen_context(system_u:object_r:virtstoraged_var_run_t,s0) [...]
I was not able to figure out on which selinux policy is this one based on as the upstream for rawhide from <https://github.com/fedora-selinux/selinux-policy.git> is a bit different. There are some cosmetics changes but I see two major differences:
- the upstream policy doesn't have split-daemon bits compared to this one, I checked it and it looks reasonable but I'm not that familiar with selinux policy Now I compare the two, I see there's a bunch of stuff in the current fedora virt.te that doesn't exist in this virt.te.
This policy has been mostly rewritten by Nikola Knazekova to work with the split daemon configuration.
It's only been tested using libvirt-tck and by running some VM by hand so we could use your help running other tests you have available.
There has actually been some progress on the policy since I last updated the PR. The latest version is available here: https://github.com/5umm3r15/selinux-policy/blob/libvirt-selinux/policy/modul...
https://github.com/5umm3r15/selinux-policy/blob/libvirt-selinux/policy/modul...
https://github.com/5umm3r15/selinux-policy/blob/libvirt-selinux/policy/modul...
The MLS parts of the policy are still not 100% since we are not sure about some access that is taking place during testing with libvirt-tck.
Please see: https://gitlab.com/libvirt/libvirt-tck/-/merge_requests/8#note_601463944
Doh I missed those questions.
So if we deploy this, then its likely to break stuff that's in the current virt.te that we've omitted.
I should have checked this more closely before re-sendig, as I just blindly assumed that the differences to fedora-selinux had been eliminated after my original review comments :-(
- the upstream policy has important `system.token` issue fix that we've seen recently introduced by upstream commit <1f761d0bbd>
My view for pulling any SElinux policy into libvirt.git is that we need to untangle the current fedora selinux virt policy first to remove all the non-libvirt pieces. It should then be a direct copy into libvirt.git with no modifications.
So I don't think this is mergable as it exists now.
The policy has been split to virt and virt_supplementary (https://github.com/5umm3r15/selinux-policy/blob/libvirt-selinux/policy/modul...), where virt_supplementary has the bits that are non-libvirt (this part will stay in selinux-policy repo).
IIUC, the repo 5umm3r15/selinux-policy is not the main repo used for Fedora policy. If I merged this policy in libvirt now, and we deployed it on Fedora we would regress becaue virt_supplementary doesn't exist in any current Fedora / rawhide IIUC. Is there an ETA for merging the virt/virt_supplementary stuff into the official Fedora policy, and updating rawhide / RHEL-9, so that we can in turn merge & release the libvirt parts ? 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 :|

On 20. 08. 21 13:33, Daniel P. Berrangé wrote:
On Thu, Aug 19, 2021 at 05:23:48PM +0200, Vit Mojzis wrote:
On 10. 08. 21 18:35, Daniel P. Berrangé wrote:
On Tue, Aug 10, 2021 at 10:39:23AM +0200, Pavel Hrdina wrote:
On Fri, Aug 06, 2021 at 06:47:58PM +0100, Daniel P. Berrangé wrote:
From: Nikola Knazekova <nknazeko@redhat.com>
SELinux policy was created for:
Hypervisor drivers: - virtqemud (QEMU/KVM) - virtlxcd (LXC) - virtvboxd (VirtualBox)
Secondary drivers: - virtstoraged (host storage mgmt) - virtnetworkd (virtual network mgmt) - virtinterface (network interface mgmt) - virtnodedevd (physical device mgmt) - virtsecretd (security credential mgmt) - virtnwfilterd (ip[6]tables/ebtables mgmt) - virtproxyd (proxy daemon)
SELinux policy for virtvxz and virtxend has not been created yet, because I wasn't able to reproduce AVC messages. These drivers run in unconfined_domain until the AVC messages are reproduced internally and policy for these drivers is made.
Signed-off-by: Nikola Knazekova <nknazeko@redhat.com> --- src/security/selinux/virt.fc | 111 ++ src/security/selinux/virt.if | 1984 ++++++++++++++++++++++++++++++++ src/security/selinux/virt.te | 2078 ++++++++++++++++++++++++++++++++++ 3 files changed, 4173 insertions(+) create mode 100644 src/security/selinux/virt.fc create mode 100644 src/security/selinux/virt.if create mode 100644 src/security/selinux/virt.te
diff --git a/src/security/selinux/virt.fc b/src/security/selinux/virt.fc new file mode 100644 index 0000000000..554e1094d9 --- /dev/null +++ b/src/security/selinux/virt.fc @@ -0,0 +1,111 @@ +HOME_DIR/\.libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.cache/libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.cache/libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.config/libvirt(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/\.config/libvirt/qemu(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/VirtualMachines(/.*)? gen_context(system_u:object_r:virt_home_t,s0) +HOME_DIR/VirtualMachines/isos(/.*)? gen_context(system_u:object_r:virt_content_t,s0) These two doesn't look like libvirt selinux bits, more like virt-manager or some other tool. Rationale is largely lost in the mists of time to be honest. $HOME/VirtualMachines does make sense for desktop virt use case I think, while the below rules make sense as a direct translation of libvirt's system paths.
I think its ok to have both really
+HOME_DIR/\.local/share/libvirt/images(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +HOME_DIR/\.local/share/libvirt/boot(/.*)? gen_context(system_u:object_r:svirt_home_t,s0) +/var/lib/libvirt(/.*)? gen_context(system_u:object_r:virt_var_lib_t,s0) +/var/lib/libvirt/boot(/.*)? gen_context(system_u:object_r:virt_content_t,s0) +/var/lib/libvirt/images(/.*)? gen_context(system_u:object_r:virt_image_t,s0) +/var/lib/libvirt/isos(/.*)? gen_context(system_u:object_r:virt_content_t,s0) +/var/lib/libvirt/lockd(/.*)? gen_context(system_u:object_r:virt_var_lockd_t,s0) +/var/lib/libvirt/qemu(/.*)? gen_context(system_u:object_r:qemu_var_run_t,s0-mls_systemhigh) + +/var/log/log(/.*)? gen_context(system_u:object_r:virt_log_t,s0) Based on commit from selinux-policy 63ead48cf8 this seems vdsm related. I don't think that we use this directory in libvirt. Yeah, that's dubious. Good point, we'll move it out of virt policy. +/var/log/libvirt(/.*)? gen_context(system_u:object_r:virt_log_t,s0) +/var/run/libvirtd\.pid -- gen_context(system_u:object_r:virt_var_run_t,s0) +# Avoid calling m4's "interface" by using en empty string +/var/run/libvirt/interfac(e)(/.*)? gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/libvirt/nodedev(/.*)? gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/libvirt/nwfilter(/.*)? gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/libvirt/secrets(/.*)? gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/libvirt/storage(/.*)? gen_context(system_u:object_r:virtstoraged_var_run_t,s0) + +/var/run/virtlogd\.pid -- gen_context(system_u:object_r:virtlogd_var_run_t,s0) +/var/run/virtlxcd\.pid -- gen_context(system_u:object_r:virt_lxc_var_run_t,s0) +/var/run/virtqemud\.pid -- gen_context(system_u:object_r:virtqemud_var_run_t,s0) +/var/run/virtvboxd\.pid -- gen_context(system_u:object_r:virtvboxd_var_run_t,s0) +/var/run/virtproxyd\.pid -- gen_context(system_u:object_r:virtproxyd_var_run_t,s0) +/var/run/virtinterfaced\.pid -- gen_context(system_u:object_r:virtinterfaced_var_run_t,s0) +/var/run/virtnetworkd\.pid -- gen_context(system_u:object_r:virtnetworkd_var_run_t,s0) +/var/run/virtnodedevd\.pid -- gen_context(system_u:object_r:virtnodedevd_var_run_t,s0) +/var/run/virtnwfilterd\.pid -- gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/virtnwfilterd-binding\.pid -- gen_context(system_u:object_r:virtnwfilterd_var_run_t,s0) +/var/run/virtsecretd\.pid -- gen_context(system_u:object_r:virtsecretd_var_run_t,s0) +/var/run/virtstoraged\.pid -- gen_context(system_u:object_r:virtstoraged_var_run_t,s0) [...]
I was not able to figure out on which selinux policy is this one based on as the upstream for rawhide from <https://github.com/fedora-selinux/selinux-policy.git> is a bit different. There are some cosmetics changes but I see two major differences:
- the upstream policy doesn't have split-daemon bits compared to this one, I checked it and it looks reasonable but I'm not that familiar with selinux policy Now I compare the two, I see there's a bunch of stuff in the current fedora virt.te that doesn't exist in this virt.te. This policy has been mostly rewritten by Nikola Knazekova to work with the split daemon configuration.
It's only been tested using libvirt-tck and by running some VM by hand so we could use your help running other tests you have available.
There has actually been some progress on the policy since I last updated the PR. The latest version is available here: https://github.com/5umm3r15/selinux-policy/blob/libvirt-selinux/policy/modul...
https://github.com/5umm3r15/selinux-policy/blob/libvirt-selinux/policy/modul...
https://github.com/5umm3r15/selinux-policy/blob/libvirt-selinux/policy/modul...
The MLS parts of the policy are still not 100% since we are not sure about some access that is taking place during testing with libvirt-tck.
Please see: https://gitlab.com/libvirt/libvirt-tck/-/merge_requests/8#note_601463944 Doh I missed those questions.
So if we deploy this, then its likely to break stuff that's in the current virt.te that we've omitted.
I should have checked this more closely before re-sendig, as I just blindly assumed that the differences to fedora-selinux had been eliminated after my original review comments :-(
- the upstream policy has important `system.token` issue fix that we've seen recently introduced by upstream commit <1f761d0bbd>
My view for pulling any SElinux policy into libvirt.git is that we need to untangle the current fedora selinux virt policy first to remove all the non-libvirt pieces. It should then be a direct copy into libvirt.git with no modifications.
So I don't think this is mergable as it exists now. The policy has been split to virt and virt_supplementary (https://github.com/5umm3r15/selinux-policy/blob/libvirt-selinux/policy/modul...), where virt_supplementary has the bits that are non-libvirt (this part will stay in selinux-policy repo). IIUC, the repo 5umm3r15/selinux-policy is not the main repo used for Fedora policy.
Yes, it's a fork.
If I merged this policy in libvirt now, and we deployed it on Fedora we would regress becaue virt_supplementary doesn't exist in any current Fedora / rawhide IIUC.
Yes, we need to deploy it on Fedora first.
Is there an ETA for merging the virt/virt_supplementary stuff into the official Fedora policy, and updating rawhide / RHEL-9, so that we can in turn merge & release the libvirt parts ?
We'll deploy it in rawhide as soon as we get the MLS part sorted. No ETA at this point. Vit
Regards, Daniel

From: Vit Mojzis <vmojzis@redhat.com> Compile the policy using a script executed by meson. Generate 2 versions of the binary policy to allow installation to systems with any selinux type (targeted, mls and minimum). Signed-off-by: Vit Mojzis <vmojzis@redhat.com> --- libvirt.spec.in | 92 ++++++++++++++++ src/security/meson.build | 13 +++ src/security/selinux/compile_policy.py | 144 +++++++++++++++++++++++++ src/security/selinux/mcs/meson.build | 20 ++++ src/security/selinux/meson.build | 7 ++ src/security/selinux/mls/meson.build | 20 ++++ 6 files changed, 296 insertions(+) create mode 100755 src/security/selinux/compile_policy.py create mode 100644 src/security/selinux/mcs/meson.build create mode 100644 src/security/selinux/meson.build create mode 100644 src/security/selinux/mls/meson.build diff --git a/libvirt.spec.in b/libvirt.spec.in index c3f50224cc..aa50db3c16 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -3,6 +3,12 @@ # This spec file assumes you are building on a Fedora or RHEL version # that's still supported by the vendor. It may work on other distros # or versions, but no effort will be made to ensure that going forward. + +%if 0%{?fedora} > 34 || 0%{?rhel} > 8 + %global with_selinux 1 + %global modulename virt +%endif + %define min_rhel 8 %define min_fedora 33 @@ -427,6 +433,12 @@ Requires(pre): shadow-utils # Needed by /usr/libexec/libvirt-guests.sh script. Requires: gettext +%if 0%{?with_selinux} +# This ensures that the *-selinux package and all it’s dependencies are not pulled +# into containers and other systems that do not use SELinux +Requires: (%{name}-daemon-selinux if selinux-policy-base) +%endif + # Ensure smooth upgrades Obsoletes: libvirt-admin < 7.3.0 Provides: libvirt-admin = %{version}-%{release} @@ -930,6 +942,19 @@ Requires: libvirt-daemon-driver-network = %{version}-%{release} %description nss Libvirt plugin for NSS for translating domain names into IP addresses. +%if 0%{?with_selinux} +# SELinux subpackage +%package daemon-selinux +Summary: Libvirt daemon SELinux policy +Requires: selinux-policy-base +Requires(post): selinux-policy-base +BuildRequires: selinux-policy-devel +BuildArch: noarch +%{?selinux_requires} + +%description daemon-selinux +SELinux policy module for libvirt daemons. +%endif %prep @@ -1603,6 +1628,63 @@ getent group virtlogin >/dev/null || groupadd -r virtlogin exit 0 %endif +%if 0%{?with_selinux} +# SELinux contexts are saved so that only affected files can be +# relabeled after the policy module installation +%pre daemon-selinux +if [ -e /etc/selinux/config ]; then + . /etc/selinux/config + %selinux_relabel_pre -s ${SELINUXTYPE} +fi + +%post daemon-selinux +# only policy reload is needed - module installation is managed by triggers +/usr/sbin/selinuxenabled && /usr/sbin/load_policy || : + +%postun daemon-selinux +if [ $1 -eq 0 ]; then + /usr/sbin/selinuxenabled && /usr/sbin/load_policy || : +fi + +%posttrans daemon-selinux +if [ -e /etc/selinux/config ]; then + . /etc/selinux/config + %selinux_relabel_post -s ${SELINUXTYPE} +fi + +# install the policy module to corresponding policy store if +# selinux-policy-{targeted|mls|minimum} package is installed on the system +%triggerin -n %{name}-daemon-selinux -- selinux-policy-targeted +/usr/sbin/semodule -n -s targeted -X 200 -i %{_datadir}/selinux/packages/%{modulename}.pp.bz2 || : + +%triggerin -n %{name}-daemon-selinux -- selinux-policy-minimum +/usr/sbin/semodule -n -s minimum -X 200 -i %{_datadir}/selinux/packages/%{modulename}.pp.bz2 || : +# libvirt module is installed by default, but disabled -- enable it +/usr/sbin/semodule -n -s minimum -e %{modulename} || : + +%triggerin -n %{name}-daemon-selinux -- selinux-policy-mls +/usr/sbin/semodule -n -s mls -X 200 -i %{_datadir}/selinux/packages/mls/%{modulename}.pp.bz2 || : + +# remove the policy module from corresponding module store if +# libvirt-selinux or selinux-policy-* was removed from the system, +# but not when either package gets updated +%triggerun -n %{name}-daemon-selinux -- selinux-policy-targeted +if ([ $1 -eq 0 ] || [ $2 -eq 0 ]) && [ -e %{_sharedstatedir}/selinux/targeted/active/modules/200/%{modulename} ]; then + /usr/sbin/semodule -n -s targeted -X 200 -r %{modulename} || : +fi + +%triggerun -n %{name}-daemon-selinux -- selinux-policy-minimum +if ([ $1 -eq 0 ] || [ $2 -eq 0 ]) && [ -e %{_sharedstatedir}/selinux/minimum/active/modules/200/%{modulename} ]; then + /usr/sbin/semodule -n -s minimum -X 200 -r %{modulename} || : + /usr/sbin/semodule -n -d %{modulename} || : +fi + +%triggerun -n %{name}-daemon-selinux -- selinux-policy-mls +if ([ $1 -eq 0 ] || [ $2 -eq 0 ]) && [ -e %{_sharedstatedir}/selinux/mls/active/modules/200/%{modulename} ]; then + /usr/sbin/semodule -n -s mls -X 200 -r %{modulename} || : +fi +%endif + %files %files docs @@ -2063,5 +2145,15 @@ exit 0 %{_datadir}/libvirt/api/libvirt-qemu-api.xml %{_datadir}/libvirt/api/libvirt-lxc-api.xml +%if 0%{?with_selinux} +%files daemon-selinux +%{_datadir}/selinux/packages/%{modulename}.pp.* +%{_datadir}/selinux/packages/mls/%{modulename}.pp.* +%ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/targeted/active/modules/200/%{modulename} +%ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/minimum/active/modules/200/%{modulename} +%ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/mls/active/modules/200/%{modulename} +%{_datadir}/selinux/devel/include/distributed/%{modulename}.if +%endif + %changelog diff --git a/src/security/meson.build b/src/security/meson.build index 6f5e1dec1d..ac360fa37a 100644 --- a/src/security/meson.build +++ b/src/security/meson.build @@ -55,3 +55,16 @@ endif if conf.has('WITH_APPARMOR_PROFILES') subdir('apparmor') endif + +os_release = run_command('grep', '^ID=', '/etc/os-release').stdout() +os_version = run_command('grep', '^VERSION_ID=', '/etc/os-release').stdout().split('=') +if (os_version.length() == 2) + os_version = os_version[1] +else + os_version = 0 +endif + +if ((os_release.contains('fedora') and os_version.version_compare('>33')) or + (os_release.contains('rhel') and os_version.version_compare('>8'))) + subdir('selinux') +endif diff --git a/src/security/selinux/compile_policy.py b/src/security/selinux/compile_policy.py new file mode 100755 index 0000000000..95f0741d1a --- /dev/null +++ b/src/security/selinux/compile_policy.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2021 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see +# <http://www.gnu.org/licenses/>. + +# This script is based on selinux-policy Makefile +# https://github.com/fedora-selinux/selinux-policy/blob/rawhide/support/Makefi... + +import subprocess +import sys +import os +import glob + +if len(sys.argv) != 7: + print(("Usage: {} <policy>.te <policy>.if <policy>.fc <output>.pp <tmpdir>" + " <type (mls/mcs)>").format(sys.argv[0]), file=sys.stderr) + exit(os.EX_USAGE) + +module_name = os.path.splitext(os.path.basename(sys.argv[1]))[0] + +m4param = ["-D", "distro_redhat", "-D", "hide_broken_symptoms", + "-D", "mls_num_sens=16", "-D", "mls_num_cats=1024", + "-D", "mcs_num_cats=1024"] + +if sys.argv[6] == "mls": + m4param = ["-D", "enable_mls"] + m4param +else: + m4param = ["-D", "enable_mcs"] + m4param + +SHAREDIR = "/usr/share/selinux" +HEADERDIR = os.path.join(SHAREDIR, "devel/include") + +m4support = sorted(glob.glob("{}/support/*.spt".format(HEADERDIR))) +header_layers = glob.glob("{}/*/".format(HEADERDIR)) +header_layers = sorted([x for x in header_layers + if os.path.join(HEADERDIR, "support") not in x]) + +header_interfaces = [] +for layer in header_layers: + header_interfaces.extend(glob.glob("{}/*.if".format(layer))) +header_interfaces.sort() + +# prepare temp folder +try: + os.makedirs(sys.argv[5]) +except Exception: + pass + +# remove old trash from the temp folder +tmpfiles = ["{}.{}".format(module_name, ext) + for ext in ["mod", "mod.fc", "tmp"]] +for name in ["iferror.m4", "all_interfaces.conf"] + tmpfiles: + try: + os.remove(os.path.join(sys.argv[5], name)) + except Exception: + pass + +# tmp/all_interfaces.conf +# echo "ifdef(\`__if_error',\`m4exit(1)')" > $5/iferror.m4 +with open(os.path.join(sys.argv[5], "iferror.m4"), "w") as file: + file.write("ifdef(`__if_error',`m4exit(1)')\n") + +# echo "divert(-1)" > $5/all_interfaces.conf +with open(os.path.join(sys.argv[5], "all_interfaces.conf"), "w") as int_file: + int_file.write("divert(-1)\n") + +# m4 $M4SUPPORT $HEADER_INTERFACES $2 $5/iferror.m4 +# | sed -e s/dollarsstar/\$\$\*/g >> $5/all_interfaces.conf +m4_run = subprocess.run(r"m4 {} | sed -e s/dollarsstar/\$\$\*/g >> {}".format( + " ".join([*m4support, *header_interfaces, sys.argv[2], + os.path.join(sys.argv[5], "iferror.m4")]), + os.path.join(sys.argv[5], "all_interfaces.conf")), + shell=True, check=True, stderr=subprocess.PIPE, + universal_newlines=True) + +# Filter out messages about duplicate definition of interfaces. e.g. +# virt.if:13: Error: duplicate definition of virt_stub_lxc(). Original +# definition on 13. +# They are expected and can be safely ignored. +for line in m4_run.stderr.split('\n'): + if line and "Error: duplicate definition of" not in line: + print(line, file=sys.stderr) + +# doesn't work properly without "shell=True" +# m4_process = Popen(["m4", *m4support, *header_interfaces, sys.argv[2], +# os.path.join(sys.argv[5], "iferror.m4")], +# stdout=PIPE, stderr=PIPE) +# sed_process = Popen(["sed", "-e", "s/dollarsstar/\$\$\*/g"], +# stdin=m4_process.stdout, stdout=int_file) +# outs, errs = m4_process.communicate() + +# echo "divert" >> $5/all_interfaces.conf +with open(os.path.join(sys.argv[5], "all_interfaces.conf"), "a") as file: + file.write("divert\n") + +# tmp/%.mod +# m4 $M4PARAM -s $M4SUPPORT $5/all_interfaces.conf $1 > $5/$MODULE_NAME.tmp +with open(os.path.join(sys.argv[5], "{}.tmp".format(module_name)), + "w") as tmp_file: + subprocess.run(["m4", *m4param, "-s", *m4support, + os.path.join(sys.argv[5], "all_interfaces.conf"), + sys.argv[1]], stdout=tmp_file, check=True) + +# /usr/bin/checkmodule -M -m $5/$MODULE_NAME.tmp -o $5/$MODULE_NAME.mod +subprocess.run(["/usr/bin/checkmodule", + "-M", + "-m", + os.path.join(sys.argv[5], "{}.tmp".format(module_name)), + "-o", + os.path.join(sys.argv[5], "{}.mod".format(module_name))], + check=True) + + +# tmp/%.mod.fc +# m4 $M4PARAM $M4SUPPORT $3 > $5/$MODULE_NAME.mod.fc +with open(os.path.join(sys.argv[5], + "{}.mod.fc".format(module_name)), "w") as mod_fc_file: + subprocess.run(["m4", *m4param, *m4support, sys.argv[3]], + stdout=mod_fc_file, check=True) + +# %.pp +# /usr/bin/semodule_package -o $4 -m $5/$MODULE_NAME.mod +# -f $5/$MODULE_NAME.mod.fc +subprocess.run(["/usr/bin/semodule_package", + "-o", + sys.argv[4], + "-m", + os.path.join(sys.argv[5], "{}.mod".format(module_name)), + "-f", + os.path.join(sys.argv[5], "{}.mod.fc".format(module_name))], + check=True) diff --git a/src/security/selinux/mcs/meson.build b/src/security/selinux/mcs/meson.build new file mode 100644 index 0000000000..419253f151 --- /dev/null +++ b/src/security/selinux/mcs/meson.build @@ -0,0 +1,20 @@ +selinux_sources = [ + '../virt.te', + '../virt.if', + '../virt.fc', +] + +# targeted/minimum policy module +virt_pp = custom_target('virt.pp', + output : 'virt.pp', + input : selinux_sources, + command : [compile_policy_prog, '@INPUT@', '@OUTPUT@', 'selinux/mcs/tmp', 'mcs'], + install : false) + +bzip = custom_target('virt.pp.bz2', + output : 'virt.pp.bz2', + input : virt_pp, + command : [bzip2_prog, '-c', '-9', '@INPUT@'], + capture : true, + install : true, + install_dir : 'share/selinux/packages') diff --git a/src/security/selinux/meson.build b/src/security/selinux/meson.build new file mode 100644 index 0000000000..f9dde73e62 --- /dev/null +++ b/src/security/selinux/meson.build @@ -0,0 +1,7 @@ +set_variable('compile_policy_prog', find_program('compile_policy.py')) +set_variable('bzip2_prog', find_program('bzip2')) + +install_data('virt.if', install_dir : 'share/selinux/devel/include/distributed') + +subdir('mcs') +subdir('mls') diff --git a/src/security/selinux/mls/meson.build b/src/security/selinux/mls/meson.build new file mode 100644 index 0000000000..20bab41fea --- /dev/null +++ b/src/security/selinux/mls/meson.build @@ -0,0 +1,20 @@ +selinux_sources = [ + '../virt.te', + '../virt.if', + '../virt.fc', +] + +# MLS policy module +virt_pp_mls = custom_target('virt.pp', + output : 'virt.pp', + input : selinux_sources, + command : [compile_policy_prog, '@INPUT@', '@OUTPUT@', 'selinux/mls/tmp', 'mls'], + install : false) + +bzip_mls = custom_target('virt.pp.bz2', + output : 'virt.pp.bz2', + input : virt_pp_mls, + command : [bzip2_prog, '-c', '-9', '@INPUT@'], + capture : true, + install : true, + install_dir : 'share/selinux/packages/mls') -- 2.31.1

This function is only needed if we're trying to set a dynamic variable name. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/security/selinux/meson.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/security/selinux/meson.build b/src/security/selinux/meson.build index f9dde73e62..cf28769431 100644 --- a/src/security/selinux/meson.build +++ b/src/security/selinux/meson.build @@ -1,5 +1,5 @@ -set_variable('compile_policy_prog', find_program('compile_policy.py')) -set_variable('bzip2_prog', find_program('bzip2')) +compile_policy_prog = find_program('compile_policy.py') +bzip2_prog = find_program('bzip2') install_data('virt.if', install_dir : 'share/selinux/devel/include/distributed') -- 2.31.1

The majority of build helper scripts live in this directory Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- scripts/meson.build | 1 + .../compile_policy.py => scripts/selinux-compile-policy.py | 0 src/security/selinux/mcs/meson.build | 3 ++- src/security/selinux/meson.build | 1 - src/security/selinux/mls/meson.build | 3 ++- 5 files changed, 5 insertions(+), 3 deletions(-) rename src/security/selinux/compile_policy.py => scripts/selinux-compile-policy.py (100%) diff --git a/scripts/meson.build b/scripts/meson.build index 421e3d2acd..6f766b3822 100644 --- a/scripts/meson.build +++ b/scripts/meson.build @@ -29,6 +29,7 @@ scripts = [ 'meson-timestamp.py', 'mock-noinline.py', 'prohibit-duplicate-header.py', + 'selinux-compile-policy.py', ] foreach name : scripts diff --git a/src/security/selinux/compile_policy.py b/scripts/selinux-compile-policy.py similarity index 100% rename from src/security/selinux/compile_policy.py rename to scripts/selinux-compile-policy.py diff --git a/src/security/selinux/mcs/meson.build b/src/security/selinux/mcs/meson.build index 419253f151..113148851e 100644 --- a/src/security/selinux/mcs/meson.build +++ b/src/security/selinux/mcs/meson.build @@ -8,7 +8,8 @@ selinux_sources = [ virt_pp = custom_target('virt.pp', output : 'virt.pp', input : selinux_sources, - command : [compile_policy_prog, '@INPUT@', '@OUTPUT@', 'selinux/mcs/tmp', 'mcs'], + command : [selinux_compile_policy_prog, '@INPUT@', '@OUTPUT@', + 'selinux/mcs/tmp', 'mcs'], install : false) bzip = custom_target('virt.pp.bz2', diff --git a/src/security/selinux/meson.build b/src/security/selinux/meson.build index cf28769431..8db485a561 100644 --- a/src/security/selinux/meson.build +++ b/src/security/selinux/meson.build @@ -1,4 +1,3 @@ -compile_policy_prog = find_program('compile_policy.py') bzip2_prog = find_program('bzip2') install_data('virt.if', install_dir : 'share/selinux/devel/include/distributed') diff --git a/src/security/selinux/mls/meson.build b/src/security/selinux/mls/meson.build index 20bab41fea..7f3233f1bd 100644 --- a/src/security/selinux/mls/meson.build +++ b/src/security/selinux/mls/meson.build @@ -8,7 +8,8 @@ selinux_sources = [ virt_pp_mls = custom_target('virt.pp', output : 'virt.pp', input : selinux_sources, - command : [compile_policy_prog, '@INPUT@', '@OUTPUT@', 'selinux/mls/tmp', 'mls'], + command : [selinux_compile_policy_prog, '@INPUT@', '@OUTPUT@', + 'selinux/mls/tmp', 'mls'], install : false) bzip_mls = custom_target('virt.pp.bz2', -- 2.31.1

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- scripts/selinux-compile-policy.py | 18 +++++++++++------- src/security/selinux/mcs/meson.build | 3 ++- src/security/selinux/meson.build | 2 ++ src/security/selinux/mls/meson.build | 3 ++- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/scripts/selinux-compile-policy.py b/scripts/selinux-compile-policy.py index 95f0741d1a..31b9113a5d 100755 --- a/scripts/selinux-compile-policy.py +++ b/scripts/selinux-compile-policy.py @@ -24,9 +24,10 @@ import sys import os import glob -if len(sys.argv) != 7: - print(("Usage: {} <policy>.te <policy>.if <policy>.fc <output>.pp <tmpdir>" - " <type (mls/mcs)>").format(sys.argv[0]), file=sys.stderr) +if len(sys.argv) != 9: + print("Usage: {} <policy>.te <policy>.if <policy>.fc <output>.pp " + "<tmpdir> <type (mls/mcs)> <checkmodpath> <semodpath>" + .format(sys.argv[0]), file=sys.stderr) exit(os.EX_USAGE) module_name = os.path.splitext(os.path.basename(sys.argv[1]))[0] @@ -40,6 +41,9 @@ if sys.argv[6] == "mls": else: m4param = ["-D", "enable_mcs"] + m4param +checkmod_path = sys.argv[7] +semod_path = sys.argv[8] + SHAREDIR = "/usr/share/selinux" HEADERDIR = os.path.join(SHAREDIR, "devel/include") @@ -114,8 +118,8 @@ with open(os.path.join(sys.argv[5], "{}.tmp".format(module_name)), os.path.join(sys.argv[5], "all_interfaces.conf"), sys.argv[1]], stdout=tmp_file, check=True) -# /usr/bin/checkmodule -M -m $5/$MODULE_NAME.tmp -o $5/$MODULE_NAME.mod -subprocess.run(["/usr/bin/checkmodule", +# checkmodule -M -m $5/$MODULE_NAME.tmp -o $5/$MODULE_NAME.mod +subprocess.run([checkmod_path, "-M", "-m", os.path.join(sys.argv[5], "{}.tmp".format(module_name)), @@ -132,9 +136,9 @@ with open(os.path.join(sys.argv[5], stdout=mod_fc_file, check=True) # %.pp -# /usr/bin/semodule_package -o $4 -m $5/$MODULE_NAME.mod +# semodule_package -o $4 -m $5/$MODULE_NAME.mod # -f $5/$MODULE_NAME.mod.fc -subprocess.run(["/usr/bin/semodule_package", +subprocess.run([semod_path, "-o", sys.argv[4], "-m", diff --git a/src/security/selinux/mcs/meson.build b/src/security/selinux/mcs/meson.build index 113148851e..0f2edc2b76 100644 --- a/src/security/selinux/mcs/meson.build +++ b/src/security/selinux/mcs/meson.build @@ -9,7 +9,8 @@ virt_pp = custom_target('virt.pp', output : 'virt.pp', input : selinux_sources, command : [selinux_compile_policy_prog, '@INPUT@', '@OUTPUT@', - 'selinux/mcs/tmp', 'mcs'], + 'selinux/mcs/tmp', 'mcs', + checkmod_prog, semod_prog], install : false) bzip = custom_target('virt.pp.bz2', diff --git a/src/security/selinux/meson.build b/src/security/selinux/meson.build index 8db485a561..bd9abc9a33 100644 --- a/src/security/selinux/meson.build +++ b/src/security/selinux/meson.build @@ -1,3 +1,5 @@ +semod_prog = find_program('semodule_package') +checkmod_prog = find_program('checkmodule') bzip2_prog = find_program('bzip2') install_data('virt.if', install_dir : 'share/selinux/devel/include/distributed') diff --git a/src/security/selinux/mls/meson.build b/src/security/selinux/mls/meson.build index 7f3233f1bd..2c866c548c 100644 --- a/src/security/selinux/mls/meson.build +++ b/src/security/selinux/mls/meson.build @@ -9,7 +9,8 @@ virt_pp_mls = custom_target('virt.pp', output : 'virt.pp', input : selinux_sources, command : [selinux_compile_policy_prog, '@INPUT@', '@OUTPUT@', - 'selinux/mls/tmp', 'mls'], + 'selinux/mls/tmp', 'mls', + checkmod_prog, semod_prog], install : false) bzip_mls = custom_target('virt.pp.bz2', -- 2.31.1

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- meson_options.txt | 1 + scripts/selinux-compile-policy.py | 15 +++++++-------- src/security/selinux/mcs/meson.build | 3 ++- src/security/selinux/meson.build | 2 ++ src/security/selinux/mls/meson.build | 3 ++- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/meson_options.txt b/meson_options.txt index 859ed36b8f..7287cf1222 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -39,6 +39,7 @@ option('sanlock', type: 'feature', value: 'auto', description: 'sanlock support' option('sasl', type: 'feature', value: 'auto', description: 'sasl support') option('selinux', type: 'feature', value: 'auto', description: 'selinux support') option('selinux_mount', type: 'string', value: '', description: 'set SELinux mount point') +option('selinux_policy_includes', type: 'string', value: '/usr/share/selinux/devel/include', description: 'SELinux policy include directory') option('udev', type: 'feature', value: 'auto', description: 'udev support') option('wireshark_dissector', type: 'feature', value: 'auto', description: 'wireshark support') option('wireshark_plugindir', type: 'string', value: '', description: 'wireshark plugins directory for use when installing wireshark plugin') diff --git a/scripts/selinux-compile-policy.py b/scripts/selinux-compile-policy.py index 31b9113a5d..3890b4e55a 100755 --- a/scripts/selinux-compile-policy.py +++ b/scripts/selinux-compile-policy.py @@ -24,9 +24,10 @@ import sys import os import glob -if len(sys.argv) != 9: +if len(sys.argv) != 10: print("Usage: {} <policy>.te <policy>.if <policy>.fc <output>.pp " - "<tmpdir> <type (mls/mcs)> <checkmodpath> <semodpath>" + "<tmpdir> <type (mls/mcs)> <checkmodpath> <semodpath> " + "<policyincludepath>" .format(sys.argv[0]), file=sys.stderr) exit(os.EX_USAGE) @@ -43,14 +44,12 @@ else: checkmod_path = sys.argv[7] semod_path = sys.argv[8] +policy_includes = sys.argv[9] -SHAREDIR = "/usr/share/selinux" -HEADERDIR = os.path.join(SHAREDIR, "devel/include") - -m4support = sorted(glob.glob("{}/support/*.spt".format(HEADERDIR))) -header_layers = glob.glob("{}/*/".format(HEADERDIR)) +m4support = sorted(glob.glob("{}/support/*.spt".format(policy_includes))) +header_layers = glob.glob("{}/*/".format(policy_includes)) header_layers = sorted([x for x in header_layers - if os.path.join(HEADERDIR, "support") not in x]) + if os.path.join(policy_includes, "support") not in x]) header_interfaces = [] for layer in header_layers: diff --git a/src/security/selinux/mcs/meson.build b/src/security/selinux/mcs/meson.build index 0f2edc2b76..9ecfe976db 100644 --- a/src/security/selinux/mcs/meson.build +++ b/src/security/selinux/mcs/meson.build @@ -10,7 +10,8 @@ virt_pp = custom_target('virt.pp', input : selinux_sources, command : [selinux_compile_policy_prog, '@INPUT@', '@OUTPUT@', 'selinux/mcs/tmp', 'mcs', - checkmod_prog, semod_prog], + checkmod_prog, semod_prog, + selinux_policy_includes], install : false) bzip = custom_target('virt.pp.bz2', diff --git a/src/security/selinux/meson.build b/src/security/selinux/meson.build index bd9abc9a33..dda8730141 100644 --- a/src/security/selinux/meson.build +++ b/src/security/selinux/meson.build @@ -2,6 +2,8 @@ semod_prog = find_program('semodule_package') checkmod_prog = find_program('checkmodule') bzip2_prog = find_program('bzip2') +selinux_policy_includes = get_option('selinux_policy_includes') + install_data('virt.if', install_dir : 'share/selinux/devel/include/distributed') subdir('mcs') diff --git a/src/security/selinux/mls/meson.build b/src/security/selinux/mls/meson.build index 2c866c548c..ef72a5f5ec 100644 --- a/src/security/selinux/mls/meson.build +++ b/src/security/selinux/mls/meson.build @@ -10,7 +10,8 @@ virt_pp_mls = custom_target('virt.pp', input : selinux_sources, command : [selinux_compile_policy_prog, '@INPUT@', '@OUTPUT@', 'selinux/mls/tmp', 'mls', - checkmod_prog, semod_prog], + checkmod_prog, semod_prog, + selinux_policy_includes], install : false) bzip_mls = custom_target('virt.pp.bz2', -- 2.31.1

It is currently mixed in with the comment and variables controlling the min OS version. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- libvirt.spec.in | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libvirt.spec.in b/libvirt.spec.in index aa50db3c16..37f8a218e6 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -4,11 +4,6 @@ # that's still supported by the vendor. It may work on other distros # or versions, but no effort will be made to ensure that going forward. -%if 0%{?fedora} > 34 || 0%{?rhel} > 8 - %global with_selinux 1 - %global modulename virt -%endif - %define min_rhel 8 %define min_fedora 33 @@ -192,6 +187,11 @@ %define with_modular_daemons 1 %endif +%if 0%{?fedora} > 34 || 0%{?rhel} > 8 + %global with_selinux 1 + %global modulename virt +%endif + # Force QEMU to run as non-root %define qemu_user qemu %define qemu_group qemu -- 2.31.1

On Fri, Aug 06, 2021 at 06:48:04PM +0100, Daniel P. Berrangé wrote:
It is currently mixed in with the comment and variables controlling the min OS version.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- libvirt.spec.in | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in index aa50db3c16..37f8a218e6 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -4,11 +4,6 @@ # that's still supported by the vendor. It may work on other distros # or versions, but no effort will be made to ensure that going forward.
Just a nitpick, this leaves empty line here which was introduced by the second patch in the series. Pavel
-%if 0%{?fedora} > 34 || 0%{?rhel} > 8 - %global with_selinux 1 - %global modulename virt -%endif - %define min_rhel 8 %define min_fedora 33
@@ -192,6 +187,11 @@ %define with_modular_daemons 1 %endif
+%if 0%{?fedora} > 34 || 0%{?rhel} > 8 + %global with_selinux 1 + %global modulename virt +%endif + # Force QEMU to run as non-root %define qemu_user qemu %define qemu_group qemu -- 2.31.1

This new name of the option makes it clear that the conditional only affects policy installation, not building of selinux support more generally. The prefix on the module name avoids risk of clashing with other variables. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- libvirt.spec.in | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/libvirt.spec.in b/libvirt.spec.in index 37f8a218e6..bb693b58bf 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -187,9 +187,10 @@ %define with_modular_daemons 1 %endif +%define with_selinux_policy 0 +%global selinux_modulename virt %if 0%{?fedora} > 34 || 0%{?rhel} > 8 - %global with_selinux 1 - %global modulename virt + %global with_selinux_policy 1 %endif # Force QEMU to run as non-root @@ -433,7 +434,7 @@ Requires(pre): shadow-utils # Needed by /usr/libexec/libvirt-guests.sh script. Requires: gettext -%if 0%{?with_selinux} +%if 0%{?with_selinux_policy} # This ensures that the *-selinux package and all it’s dependencies are not pulled # into containers and other systems that do not use SELinux Requires: (%{name}-daemon-selinux if selinux-policy-base) @@ -942,7 +943,7 @@ Requires: libvirt-daemon-driver-network = %{version}-%{release} %description nss Libvirt plugin for NSS for translating domain names into IP addresses. -%if 0%{?with_selinux} +%if 0%{?with_selinux_policy} # SELinux subpackage %package daemon-selinux Summary: Libvirt daemon SELinux policy @@ -1628,7 +1629,7 @@ getent group virtlogin >/dev/null || groupadd -r virtlogin exit 0 %endif -%if 0%{?with_selinux} +%if 0%{?with_selinux_policy} # SELinux contexts are saved so that only affected files can be # relabeled after the policy module installation %pre daemon-selinux @@ -1655,33 +1656,33 @@ fi # install the policy module to corresponding policy store if # selinux-policy-{targeted|mls|minimum} package is installed on the system %triggerin -n %{name}-daemon-selinux -- selinux-policy-targeted -/usr/sbin/semodule -n -s targeted -X 200 -i %{_datadir}/selinux/packages/%{modulename}.pp.bz2 || : +/usr/sbin/semodule -n -s targeted -X 200 -i %{_datadir}/selinux/packages/%{selinux_modulename}.pp.bz2 || : %triggerin -n %{name}-daemon-selinux -- selinux-policy-minimum -/usr/sbin/semodule -n -s minimum -X 200 -i %{_datadir}/selinux/packages/%{modulename}.pp.bz2 || : +/usr/sbin/semodule -n -s minimum -X 200 -i %{_datadir}/selinux/packages/%{selinux_modulename}.pp.bz2 || : # libvirt module is installed by default, but disabled -- enable it -/usr/sbin/semodule -n -s minimum -e %{modulename} || : +/usr/sbin/semodule -n -s minimum -e %{selinux_modulename} || : %triggerin -n %{name}-daemon-selinux -- selinux-policy-mls -/usr/sbin/semodule -n -s mls -X 200 -i %{_datadir}/selinux/packages/mls/%{modulename}.pp.bz2 || : +/usr/sbin/semodule -n -s mls -X 200 -i %{_datadir}/selinux/packages/mls/%{selinux_modulename}.pp.bz2 || : # remove the policy module from corresponding module store if # libvirt-selinux or selinux-policy-* was removed from the system, # but not when either package gets updated %triggerun -n %{name}-daemon-selinux -- selinux-policy-targeted -if ([ $1 -eq 0 ] || [ $2 -eq 0 ]) && [ -e %{_sharedstatedir}/selinux/targeted/active/modules/200/%{modulename} ]; then - /usr/sbin/semodule -n -s targeted -X 200 -r %{modulename} || : +if ([ $1 -eq 0 ] || [ $2 -eq 0 ]) && [ -e %{_sharedstatedir}/selinux/targeted/active/modules/200/%{selinux_modulename} ]; then + /usr/sbin/semodule -n -s targeted -X 200 -r %{selinux_modulename} || : fi %triggerun -n %{name}-daemon-selinux -- selinux-policy-minimum -if ([ $1 -eq 0 ] || [ $2 -eq 0 ]) && [ -e %{_sharedstatedir}/selinux/minimum/active/modules/200/%{modulename} ]; then - /usr/sbin/semodule -n -s minimum -X 200 -r %{modulename} || : - /usr/sbin/semodule -n -d %{modulename} || : +if ([ $1 -eq 0 ] || [ $2 -eq 0 ]) && [ -e %{_sharedstatedir}/selinux/minimum/active/modules/200/%{selinux_modulename} ]; then + /usr/sbin/semodule -n -s minimum -X 200 -r %{selinux_modulename} || : + /usr/sbin/semodule -n -d %{selinux_modulename} || : fi %triggerun -n %{name}-daemon-selinux -- selinux-policy-mls -if ([ $1 -eq 0 ] || [ $2 -eq 0 ]) && [ -e %{_sharedstatedir}/selinux/mls/active/modules/200/%{modulename} ]; then - /usr/sbin/semodule -n -s mls -X 200 -r %{modulename} || : +if ([ $1 -eq 0 ] || [ $2 -eq 0 ]) && [ -e %{_sharedstatedir}/selinux/mls/active/modules/200/%{selinux_modulename} ]; then + /usr/sbin/semodule -n -s mls -X 200 -r %{selinux_modulename} || : fi %endif @@ -2145,14 +2146,14 @@ fi %{_datadir}/libvirt/api/libvirt-qemu-api.xml %{_datadir}/libvirt/api/libvirt-lxc-api.xml -%if 0%{?with_selinux} +%if 0%{?with_selinux_policy} %files daemon-selinux -%{_datadir}/selinux/packages/%{modulename}.pp.* -%{_datadir}/selinux/packages/mls/%{modulename}.pp.* -%ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/targeted/active/modules/200/%{modulename} -%ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/minimum/active/modules/200/%{modulename} -%ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/mls/active/modules/200/%{modulename} -%{_datadir}/selinux/devel/include/distributed/%{modulename}.if +%{_datadir}/selinux/packages/%{selinux_modulename}.pp.* +%{_datadir}/selinux/packages/mls/%{selinux_modulename}.pp.* +%ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/targeted/active/modules/200/%{selinux_modulename} +%ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/minimum/active/modules/200/%{selinux_modulename} +%ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/mls/active/modules/200/%{selinux_modulename} +%{_datadir}/selinux/devel/include/distributed/%{selinux_modulename}.if %endif -- 2.31.1

The /etc/os-release file may not even exist on OS and checking specific OS names / versions in the build rules duplicates conditions that are set in the RPM. Instead we just look for existance of the tools we need to build the policy module. In doing so, we also introduce '-Dselinux_policy' feature flag to let it be controlled explicitly. Since some versions will have an SELinux policy that is too old, we also need to do a feature check for the newest interface(s) that we require. Currently this is achieved by looking for "systemd_machined_stream_connect". The "macro-expander" command can be used to check for SELinux policy interfaces, as it will return empty string for any that don't exist. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- libvirt.spec.in | 7 ++++++ meson.build | 1 + meson_options.txt | 1 + src/security/meson.build | 13 +--------- src/security/selinux/meson.build | 43 ++++++++++++++++++++++++++------ 5 files changed, 46 insertions(+), 19 deletions(-) diff --git a/libvirt.spec.in b/libvirt.spec.in index bb693b58bf..d86cca7930 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1113,6 +1113,12 @@ exit 1 %define arg_remote_mode -Dremote_default_mode=legacy %endif +%if %{with_selinux_policy} + %define arg_selinux_policy -Dselinux_policy=enabled +%else + %define arg_selinux_policy -Dselinux_policy=disabled +%endif + %define when %(date +"%%F-%%T") %define where %(hostname) %define who %{?packager}%{!?packager:Unknown} @@ -1165,6 +1171,7 @@ export SOURCE_DATE_EPOCH=$(stat --printf='%Y' %{_specdir}/%{name}.spec) %{?arg_netcf} \ -Dselinux=enabled \ %{?arg_selinux_mount} \ + %{?arg_selinux_policy} \ -Dapparmor=disabled \ -Dapparmor_profiles=disabled \ -Dsecdriver_apparmor=disabled \ diff --git a/meson.build b/meson.build index e25dc17fc8..6ea47fa0d7 100644 --- a/meson.build +++ b/meson.build @@ -2302,6 +2302,7 @@ summary(storagedriver_summary, section: 'Storage Drivers', bool_yn: true) secdriver_summary = { 'SELinux': conf.has('WITH_SECDRIVER_SELINUX'), + 'sVirt policy': selinux_policy, 'AppArmor': conf.has('WITH_SECDRIVER_APPARMOR'), } summary(secdriver_summary, section: 'Security Drivers', bool_yn: true) diff --git a/meson_options.txt b/meson_options.txt index 7287cf1222..5537758f56 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -39,6 +39,7 @@ option('sanlock', type: 'feature', value: 'auto', description: 'sanlock support' option('sasl', type: 'feature', value: 'auto', description: 'sasl support') option('selinux', type: 'feature', value: 'auto', description: 'selinux support') option('selinux_mount', type: 'string', value: '', description: 'set SELinux mount point') +option('selinux_policy', type: 'feature', value: 'auto', description: 'selinux sVirt policy') option('selinux_policy_includes', type: 'string', value: '/usr/share/selinux/devel/include', description: 'SELinux policy include directory') option('udev', type: 'feature', value: 'auto', description: 'udev support') option('wireshark_dissector', type: 'feature', value: 'auto', description: 'wireshark support') diff --git a/src/security/meson.build b/src/security/meson.build index ac360fa37a..b08c4df1cf 100644 --- a/src/security/meson.build +++ b/src/security/meson.build @@ -56,15 +56,4 @@ if conf.has('WITH_APPARMOR_PROFILES') subdir('apparmor') endif -os_release = run_command('grep', '^ID=', '/etc/os-release').stdout() -os_version = run_command('grep', '^VERSION_ID=', '/etc/os-release').stdout().split('=') -if (os_version.length() == 2) - os_version = os_version[1] -else - os_version = 0 -endif - -if ((os_release.contains('fedora') and os_version.version_compare('>33')) or - (os_release.contains('rhel') and os_version.version_compare('>8'))) - subdir('selinux') -endif +subdir('selinux') diff --git a/src/security/selinux/meson.build b/src/security/selinux/meson.build index dda8730141..af5a5e38cb 100644 --- a/src/security/selinux/meson.build +++ b/src/security/selinux/meson.build @@ -1,10 +1,39 @@ -semod_prog = find_program('semodule_package') -checkmod_prog = find_program('checkmodule') -bzip2_prog = find_program('bzip2') +selinux_policy_opt = get_option('selinux_policy') +selinux_policy = false +if not selinux_policy_opt.disabled() + semod_prog = find_program('semodule_package', required: selinux_policy_opt) + checkmod_prog = find_program('checkmodule', required: selinux_policy_opt) + macroexpander_prog = find_program('macro-expander', required: selinux_policy_opt) + bzip2_prog = find_program('bzip2') + selinux_policy_includes = get_option('selinux_policy_includes') -selinux_policy_includes = get_option('selinux_policy_includes') + if semod_prog.found() and checkmod_prog.found() and \ + bzip2_prog.found() and macroexpander_prog.found() + selinux_policy = true + else + if selinux_policy_opt.enabled() + error('selinux policy requested but required build tools are missing') + endif + endif -install_data('virt.if', install_dir : 'share/selinux/devel/include/distributed') + if selinux_policy + data = run_command(macroexpander_prog, + 'systemd_machined_stream_connect').stdout() + if data == '' + if selinux_policy_opt.enabled() + error('selinux policy version is too old, ' + + 'missing "systemd_machined_stream_connect"') + endif -subdir('mcs') -subdir('mls') + selinux_policy = false + endif + endif + + if selinux_policy + install_data('virt.if', + install_dir : 'share/selinux/devel/include/distributed') + + subdir('mcs') + subdir('mls') + endif +endif -- 2.31.1

On Fri, Aug 06, 2021 at 06:48:06PM +0100, Daniel P. Berrangé wrote:
The /etc/os-release file may not even exist on OS and checking specific OS names / versions in the build rules duplicates conditions that are set in the RPM.
Instead we just look for existance of the tools we need to build the policy module. In doing so, we also introduce '-Dselinux_policy' feature flag to let it be controlled explicitly.
Since some versions will have an SELinux policy that is too old, we also need to do a feature check for the newest interface(s) that we require. Currently this is achieved by looking for "systemd_machined_stream_connect". The "macro-expander" command can be used to check for SELinux policy interfaces, as it will return empty string for any that don't exist.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- libvirt.spec.in | 7 ++++++ meson.build | 1 + meson_options.txt | 1 + src/security/meson.build | 13 +--------- src/security/selinux/meson.build | 43 ++++++++++++++++++++++++++------ 5 files changed, 46 insertions(+), 19 deletions(-)
[...]
diff --git a/src/security/selinux/meson.build b/src/security/selinux/meson.build index dda8730141..af5a5e38cb 100644 --- a/src/security/selinux/meson.build +++ b/src/security/selinux/meson.build @@ -1,10 +1,39 @@ -semod_prog = find_program('semodule_package') -checkmod_prog = find_program('checkmodule') -bzip2_prog = find_program('bzip2') +selinux_policy_opt = get_option('selinux_policy') +selinux_policy = false +if not selinux_policy_opt.disabled() + semod_prog = find_program('semodule_package', required: selinux_policy_opt) + checkmod_prog = find_program('checkmodule', required: selinux_policy_opt) + macroexpander_prog = find_program('macro-expander', required: selinux_policy_opt) + bzip2_prog = find_program('bzip2')
Here we should use `, required: selinux_policy_opt` as well, otherwise missing bzip2 would fail the `meson setup` phase if `selinux_policy_opt` is `auto`. Pavel
+ selinux_policy_includes = get_option('selinux_policy_includes')
-selinux_policy_includes = get_option('selinux_policy_includes') + if semod_prog.found() and checkmod_prog.found() and \ + bzip2_prog.found() and macroexpander_prog.found() + selinux_policy = true + else + if selinux_policy_opt.enabled() + error('selinux policy requested but required build tools are missing') + endif + endif
-install_data('virt.if', install_dir : 'share/selinux/devel/include/distributed') + if selinux_policy + data = run_command(macroexpander_prog, + 'systemd_machined_stream_connect').stdout() + if data == '' + if selinux_policy_opt.enabled() + error('selinux policy version is too old, ' + + 'missing "systemd_machined_stream_connect"') + endif
-subdir('mcs') -subdir('mls') + selinux_policy = false + endif + endif + + if selinux_policy + install_data('virt.if', + install_dir : 'share/selinux/devel/include/distributed') + + subdir('mcs') + subdir('mls') + endif +endif -- 2.31.1

On Tue, Aug 10, 2021 at 11:10:56AM +0200, Pavel Hrdina wrote:
On Fri, Aug 06, 2021 at 06:48:06PM +0100, Daniel P. Berrangé wrote:
The /etc/os-release file may not even exist on OS and checking specific OS names / versions in the build rules duplicates conditions that are set in the RPM.
Instead we just look for existance of the tools we need to build the policy module. In doing so, we also introduce '-Dselinux_policy' feature flag to let it be controlled explicitly.
Since some versions will have an SELinux policy that is too old, we also need to do a feature check for the newest interface(s) that we require. Currently this is achieved by looking for "systemd_machined_stream_connect". The "macro-expander" command can be used to check for SELinux policy interfaces, as it will return empty string for any that don't exist.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- libvirt.spec.in | 7 ++++++ meson.build | 1 + meson_options.txt | 1 + src/security/meson.build | 13 +--------- src/security/selinux/meson.build | 43 ++++++++++++++++++++++++++------ 5 files changed, 46 insertions(+), 19 deletions(-)
[...]
diff --git a/src/security/selinux/meson.build b/src/security/selinux/meson.build index dda8730141..af5a5e38cb 100644 --- a/src/security/selinux/meson.build +++ b/src/security/selinux/meson.build @@ -1,10 +1,39 @@ -semod_prog = find_program('semodule_package') -checkmod_prog = find_program('checkmodule') -bzip2_prog = find_program('bzip2') +selinux_policy_opt = get_option('selinux_policy') +selinux_policy = false +if not selinux_policy_opt.disabled() + semod_prog = find_program('semodule_package', required: selinux_policy_opt) + checkmod_prog = find_program('checkmodule', required: selinux_policy_opt) + macroexpander_prog = find_program('macro-expander', required: selinux_policy_opt) + bzip2_prog = find_program('bzip2')
Here we should use `, required: selinux_policy_opt` as well, otherwise missing bzip2 would fail the `meson setup` phase if `selinux_policy_opt` is `auto`.
I wonder if we should also actally check for 'sed' and 'm4' since the script we're calling out to will invoke them too. 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 :|

On Tue, Aug 10, 2021 at 05:35:58PM +0100, Daniel P. Berrangé wrote:
On Tue, Aug 10, 2021 at 11:10:56AM +0200, Pavel Hrdina wrote:
On Fri, Aug 06, 2021 at 06:48:06PM +0100, Daniel P. Berrangé wrote:
The /etc/os-release file may not even exist on OS and checking specific OS names / versions in the build rules duplicates conditions that are set in the RPM.
Instead we just look for existance of the tools we need to build the policy module. In doing so, we also introduce '-Dselinux_policy' feature flag to let it be controlled explicitly.
Since some versions will have an SELinux policy that is too old, we also need to do a feature check for the newest interface(s) that we require. Currently this is achieved by looking for "systemd_machined_stream_connect". The "macro-expander" command can be used to check for SELinux policy interfaces, as it will return empty string for any that don't exist.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- libvirt.spec.in | 7 ++++++ meson.build | 1 + meson_options.txt | 1 + src/security/meson.build | 13 +--------- src/security/selinux/meson.build | 43 ++++++++++++++++++++++++++------ 5 files changed, 46 insertions(+), 19 deletions(-)
[...]
diff --git a/src/security/selinux/meson.build b/src/security/selinux/meson.build index dda8730141..af5a5e38cb 100644 --- a/src/security/selinux/meson.build +++ b/src/security/selinux/meson.build @@ -1,10 +1,39 @@ -semod_prog = find_program('semodule_package') -checkmod_prog = find_program('checkmodule') -bzip2_prog = find_program('bzip2') +selinux_policy_opt = get_option('selinux_policy') +selinux_policy = false +if not selinux_policy_opt.disabled() + semod_prog = find_program('semodule_package', required: selinux_policy_opt) + checkmod_prog = find_program('checkmodule', required: selinux_policy_opt) + macroexpander_prog = find_program('macro-expander', required: selinux_policy_opt) + bzip2_prog = find_program('bzip2')
Here we should use `, required: selinux_policy_opt` as well, otherwise missing bzip2 would fail the `meson setup` phase if `selinux_policy_opt` is `auto`.
I wonder if we should also actally check for 'sed' and 'm4' since the script we're calling out to will invoke them too.
Good point, we already check for 'sed' or 'gsed' in 'build-aux/meson.build' so we could move it to the main meson.build file. I was thinking about skipping check for 'm4' if it's already dependency of the selinux tools but there should be no harm checking it as well. Pavel

By using the 'files()' function, the sources retain knowledge of the path in which they are held. This avoids the need to duplicate the source list in each subdir. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/security/selinux/mcs/meson.build | 6 ------ src/security/selinux/meson.build | 6 ++++++ src/security/selinux/mls/meson.build | 6 ------ 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/security/selinux/mcs/meson.build b/src/security/selinux/mcs/meson.build index 9ecfe976db..4ef9f0b427 100644 --- a/src/security/selinux/mcs/meson.build +++ b/src/security/selinux/mcs/meson.build @@ -1,9 +1,3 @@ -selinux_sources = [ - '../virt.te', - '../virt.if', - '../virt.fc', -] - # targeted/minimum policy module virt_pp = custom_target('virt.pp', output : 'virt.pp', diff --git a/src/security/selinux/meson.build b/src/security/selinux/meson.build index af5a5e38cb..6f84c4e067 100644 --- a/src/security/selinux/meson.build +++ b/src/security/selinux/meson.build @@ -33,6 +33,12 @@ if not selinux_policy_opt.disabled() install_data('virt.if', install_dir : 'share/selinux/devel/include/distributed') + selinux_sources = files([ + 'virt.te', + 'virt.if', + 'virt.fc', + ]) + subdir('mcs') subdir('mls') endif diff --git a/src/security/selinux/mls/meson.build b/src/security/selinux/mls/meson.build index ef72a5f5ec..4d0b103ada 100644 --- a/src/security/selinux/mls/meson.build +++ b/src/security/selinux/mls/meson.build @@ -1,9 +1,3 @@ -selinux_sources = [ - '../virt.te', - '../virt.if', - '../virt.fc', -] - # MLS policy module virt_pp_mls = custom_target('virt.pp', output : 'virt.pp', -- 2.31.1

Instead of referencing sys.argv everywhere, use named variables to make the code easier to understand. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- scripts/selinux-compile-policy.py | 57 +++++++++++++++++-------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/scripts/selinux-compile-policy.py b/scripts/selinux-compile-policy.py index 3890b4e55a..4550f3e7cb 100755 --- a/scripts/selinux-compile-policy.py +++ b/scripts/selinux-compile-policy.py @@ -31,20 +31,27 @@ if len(sys.argv) != 10: .format(sys.argv[0]), file=sys.stderr) exit(os.EX_USAGE) -module_name = os.path.splitext(os.path.basename(sys.argv[1]))[0] +policy_te = sys.argv[1] +policy_if = sys.argv[2] +policy_fc = sys.argv[3] +policy_mod = sys.argv[4] +tmpdir = sys.argv[5] +policy_type = sys.argv[6] +checkmod_path = sys.argv[7] +semod_path = sys.argv[8] +policy_includes = sys.argv[9] + +module_name = os.path.splitext(os.path.basename(policy_te))[0] m4param = ["-D", "distro_redhat", "-D", "hide_broken_symptoms", "-D", "mls_num_sens=16", "-D", "mls_num_cats=1024", "-D", "mcs_num_cats=1024"] -if sys.argv[6] == "mls": +if policy_type == "mls": m4param = ["-D", "enable_mls"] + m4param else: m4param = ["-D", "enable_mcs"] + m4param -checkmod_path = sys.argv[7] -semod_path = sys.argv[8] -policy_includes = sys.argv[9] m4support = sorted(glob.glob("{}/support/*.spt".format(policy_includes))) header_layers = glob.glob("{}/*/".format(policy_includes)) @@ -58,7 +65,7 @@ header_interfaces.sort() # prepare temp folder try: - os.makedirs(sys.argv[5]) + os.makedirs(tmpdir) except Exception: pass @@ -67,25 +74,25 @@ tmpfiles = ["{}.{}".format(module_name, ext) for ext in ["mod", "mod.fc", "tmp"]] for name in ["iferror.m4", "all_interfaces.conf"] + tmpfiles: try: - os.remove(os.path.join(sys.argv[5], name)) + os.remove(os.path.join(tmpdir, name)) except Exception: pass # tmp/all_interfaces.conf # echo "ifdef(\`__if_error',\`m4exit(1)')" > $5/iferror.m4 -with open(os.path.join(sys.argv[5], "iferror.m4"), "w") as file: +with open(os.path.join(tmpdir, "iferror.m4"), "w") as file: file.write("ifdef(`__if_error',`m4exit(1)')\n") # echo "divert(-1)" > $5/all_interfaces.conf -with open(os.path.join(sys.argv[5], "all_interfaces.conf"), "w") as int_file: +with open(os.path.join(tmpdir, "all_interfaces.conf"), "w") as int_file: int_file.write("divert(-1)\n") # m4 $M4SUPPORT $HEADER_INTERFACES $2 $5/iferror.m4 # | sed -e s/dollarsstar/\$\$\*/g >> $5/all_interfaces.conf m4_run = subprocess.run(r"m4 {} | sed -e s/dollarsstar/\$\$\*/g >> {}".format( - " ".join([*m4support, *header_interfaces, sys.argv[2], - os.path.join(sys.argv[5], "iferror.m4")]), - os.path.join(sys.argv[5], "all_interfaces.conf")), + " ".join([*m4support, *header_interfaces, policy_if, + os.path.join(tmpdir, "iferror.m4")]), + os.path.join(tmpdir, "all_interfaces.conf")), shell=True, check=True, stderr=subprocess.PIPE, universal_newlines=True) @@ -98,40 +105,40 @@ for line in m4_run.stderr.split('\n'): print(line, file=sys.stderr) # doesn't work properly without "shell=True" -# m4_process = Popen(["m4", *m4support, *header_interfaces, sys.argv[2], -# os.path.join(sys.argv[5], "iferror.m4")], +# m4_process = Popen(["m4", *m4support, *header_interfaces, policy_if, +# os.path.join(tmpdir, "iferror.m4")], # stdout=PIPE, stderr=PIPE) # sed_process = Popen(["sed", "-e", "s/dollarsstar/\$\$\*/g"], # stdin=m4_process.stdout, stdout=int_file) # outs, errs = m4_process.communicate() # echo "divert" >> $5/all_interfaces.conf -with open(os.path.join(sys.argv[5], "all_interfaces.conf"), "a") as file: +with open(os.path.join(tmpdir, "all_interfaces.conf"), "a") as file: file.write("divert\n") # tmp/%.mod # m4 $M4PARAM -s $M4SUPPORT $5/all_interfaces.conf $1 > $5/$MODULE_NAME.tmp -with open(os.path.join(sys.argv[5], "{}.tmp".format(module_name)), +with open(os.path.join(tmpdir, "{}.tmp".format(module_name)), "w") as tmp_file: subprocess.run(["m4", *m4param, "-s", *m4support, - os.path.join(sys.argv[5], "all_interfaces.conf"), - sys.argv[1]], stdout=tmp_file, check=True) + os.path.join(tmpdir, "all_interfaces.conf"), + policy_te], stdout=tmp_file, check=True) # checkmodule -M -m $5/$MODULE_NAME.tmp -o $5/$MODULE_NAME.mod subprocess.run([checkmod_path, "-M", "-m", - os.path.join(sys.argv[5], "{}.tmp".format(module_name)), + os.path.join(tmpdir, "{}.tmp".format(module_name)), "-o", - os.path.join(sys.argv[5], "{}.mod".format(module_name))], + os.path.join(tmpdir, "{}.mod".format(module_name))], check=True) # tmp/%.mod.fc # m4 $M4PARAM $M4SUPPORT $3 > $5/$MODULE_NAME.mod.fc -with open(os.path.join(sys.argv[5], +with open(os.path.join(tmpdir, "{}.mod.fc".format(module_name)), "w") as mod_fc_file: - subprocess.run(["m4", *m4param, *m4support, sys.argv[3]], + subprocess.run(["m4", *m4param, *m4support, policy_fc], stdout=mod_fc_file, check=True) # %.pp @@ -139,9 +146,9 @@ with open(os.path.join(sys.argv[5], # -f $5/$MODULE_NAME.mod.fc subprocess.run([semod_path, "-o", - sys.argv[4], + policy_mod, "-m", - os.path.join(sys.argv[5], "{}.mod".format(module_name)), + os.path.join(tmpdir, "{}.mod".format(module_name)), "-f", - os.path.join(sys.argv[5], "{}.mod.fc".format(module_name))], + os.path.join(tmpdir, "{}.mod.fc".format(module_name))], check=True) -- 2.31.1

The os.path.join() function is called repeatedly for the same base file. Factoring this out into named variables makes the code easier to understand. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- scripts/selinux-compile-policy.py | 34 ++++++++++++++++--------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/scripts/selinux-compile-policy.py b/scripts/selinux-compile-policy.py index 4550f3e7cb..911f358ba1 100755 --- a/scripts/selinux-compile-policy.py +++ b/scripts/selinux-compile-policy.py @@ -80,19 +80,21 @@ for name in ["iferror.m4", "all_interfaces.conf"] + tmpfiles: # tmp/all_interfaces.conf # echo "ifdef(\`__if_error',\`m4exit(1)')" > $5/iferror.m4 -with open(os.path.join(tmpdir, "iferror.m4"), "w") as file: +iferror = os.path.join(tmpdir, "iferror.m4") +with open(iferror, "w") as file: file.write("ifdef(`__if_error',`m4exit(1)')\n") # echo "divert(-1)" > $5/all_interfaces.conf -with open(os.path.join(tmpdir, "all_interfaces.conf"), "w") as int_file: +all_interfaces = os.path.join(tmpdir, "all_interfaces.conf") +with open(all_interfaces, "w") as int_file: int_file.write("divert(-1)\n") # m4 $M4SUPPORT $HEADER_INTERFACES $2 $5/iferror.m4 # | sed -e s/dollarsstar/\$\$\*/g >> $5/all_interfaces.conf m4_run = subprocess.run(r"m4 {} | sed -e s/dollarsstar/\$\$\*/g >> {}".format( " ".join([*m4support, *header_interfaces, policy_if, - os.path.join(tmpdir, "iferror.m4")]), - os.path.join(tmpdir, "all_interfaces.conf")), + iferror]), + all_interfaces), shell=True, check=True, stderr=subprocess.PIPE, universal_newlines=True) @@ -106,38 +108,38 @@ for line in m4_run.stderr.split('\n'): # doesn't work properly without "shell=True" # m4_process = Popen(["m4", *m4support, *header_interfaces, policy_if, -# os.path.join(tmpdir, "iferror.m4")], +# iferror], # stdout=PIPE, stderr=PIPE) # sed_process = Popen(["sed", "-e", "s/dollarsstar/\$\$\*/g"], # stdin=m4_process.stdout, stdout=int_file) # outs, errs = m4_process.communicate() # echo "divert" >> $5/all_interfaces.conf -with open(os.path.join(tmpdir, "all_interfaces.conf"), "a") as file: +with open(all_interfaces, "a") as file: file.write("divert\n") # tmp/%.mod # m4 $M4PARAM -s $M4SUPPORT $5/all_interfaces.conf $1 > $5/$MODULE_NAME.tmp -with open(os.path.join(tmpdir, "{}.tmp".format(module_name)), - "w") as tmp_file: +module_tmp = os.path.join(tmpdir, "{}.tmp".format(module_name)) +with open(module_tmp, "w") as tmp_file: subprocess.run(["m4", *m4param, "-s", *m4support, - os.path.join(tmpdir, "all_interfaces.conf"), - policy_te], stdout=tmp_file, check=True) + all_interfaces, policy_te], stdout=tmp_file, check=True) # checkmodule -M -m $5/$MODULE_NAME.tmp -o $5/$MODULE_NAME.mod +module_mod = os.path.join(tmpdir, "{}.mod".format(module_name)) subprocess.run([checkmod_path, "-M", "-m", - os.path.join(tmpdir, "{}.tmp".format(module_name)), + module_tmp, "-o", - os.path.join(tmpdir, "{}.mod".format(module_name))], + module_mod], check=True) # tmp/%.mod.fc # m4 $M4PARAM $M4SUPPORT $3 > $5/$MODULE_NAME.mod.fc -with open(os.path.join(tmpdir, - "{}.mod.fc".format(module_name)), "w") as mod_fc_file: +module_mod_fc = os.path.join(tmpdir, "{}.mod.fc".format(module_name)) +with open(module_mod_fc, "w") as mod_fc_file: subprocess.run(["m4", *m4param, *m4support, policy_fc], stdout=mod_fc_file, check=True) @@ -148,7 +150,7 @@ subprocess.run([semod_path, "-o", policy_mod, "-m", - os.path.join(tmpdir, "{}.mod".format(module_name)), + module_mod, "-f", - os.path.join(tmpdir, "{}.mod.fc".format(module_name))], + module_mod_fc], check=True) -- 2.31.1

From: Vit Mojzis <vmojzis@redhat.com> Temporary commit for testing purposes. The change needs to be done in https://gitlab.com/libvirt/libvirt-ci/-/blob/master/guests/lcitool/lcitool/a... Signed-off-by: Vit Mojzis <vmojzis@redhat.com> --- ci/containers/centos-8.Dockerfile | 1 + ci/containers/centos-stream-8.Dockerfile | 1 + ci/containers/fedora-33.Dockerfile | 1 + ci/containers/fedora-34.Dockerfile | 1 + ci/containers/fedora-rawhide-cross-mingw32.Dockerfile | 1 + ci/containers/fedora-rawhide-cross-mingw64.Dockerfile | 1 + ci/containers/fedora-rawhide.Dockerfile | 1 + 7 files changed, 7 insertions(+) diff --git a/ci/containers/centos-8.Dockerfile b/ci/containers/centos-8.Dockerfile index 9358e69b0c..3ffe81b518 100644 --- a/ci/containers/centos-8.Dockerfile +++ b/ci/containers/centos-8.Dockerfile @@ -88,6 +88,7 @@ RUN dnf update -y && \ sanlock-devel \ scrub \ sed \ + selinux-policy-devel \ systemtap-sdt-devel \ wireshark-devel \ xfsprogs-devel \ diff --git a/ci/containers/centos-stream-8.Dockerfile b/ci/containers/centos-stream-8.Dockerfile index 3355374e67..0eb7f6e165 100644 --- a/ci/containers/centos-stream-8.Dockerfile +++ b/ci/containers/centos-stream-8.Dockerfile @@ -88,6 +88,7 @@ RUN dnf update -y && \ sanlock-devel \ scrub \ sed \ + selinux-policy-devel \ systemtap-sdt-devel \ wireshark-devel \ xfsprogs-devel \ diff --git a/ci/containers/fedora-33.Dockerfile b/ci/containers/fedora-33.Dockerfile index aed94d1256..71b2d87a88 100644 --- a/ci/containers/fedora-33.Dockerfile +++ b/ci/containers/fedora-33.Dockerfile @@ -93,6 +93,7 @@ exec "$@"' > /usr/bin/nosync && \ sanlock-devel \ scrub \ sed \ + selinux-policy-devel \ sheepdog \ systemtap-sdt-devel \ wireshark-devel \ diff --git a/ci/containers/fedora-34.Dockerfile b/ci/containers/fedora-34.Dockerfile index 53a5d67b3f..a948c6560d 100644 --- a/ci/containers/fedora-34.Dockerfile +++ b/ci/containers/fedora-34.Dockerfile @@ -93,6 +93,7 @@ exec "$@"' > /usr/bin/nosync && \ sanlock-devel \ scrub \ sed \ + selinux-policy-devel \ sheepdog \ systemtap-sdt-devel \ wireshark-devel \ diff --git a/ci/containers/fedora-rawhide-cross-mingw32.Dockerfile b/ci/containers/fedora-rawhide-cross-mingw32.Dockerfile index 93a57b3277..450f2de011 100644 --- a/ci/containers/fedora-rawhide-cross-mingw32.Dockerfile +++ b/ci/containers/fedora-rawhide-cross-mingw32.Dockerfile @@ -58,6 +58,7 @@ exec "$@"' > /usr/bin/nosync && \ rpm-build \ scrub \ sed \ + selinux-policy-devel \ sheepdog \ zfs-fuse && \ nosync dnf autoremove -y && \ diff --git a/ci/containers/fedora-rawhide-cross-mingw64.Dockerfile b/ci/containers/fedora-rawhide-cross-mingw64.Dockerfile index ed16d75479..17bf0a6a12 100644 --- a/ci/containers/fedora-rawhide-cross-mingw64.Dockerfile +++ b/ci/containers/fedora-rawhide-cross-mingw64.Dockerfile @@ -58,6 +58,7 @@ exec "$@"' > /usr/bin/nosync && \ rpm-build \ scrub \ sed \ + selinux-policy-devel \ sheepdog \ zfs-fuse && \ nosync dnf autoremove -y && \ diff --git a/ci/containers/fedora-rawhide.Dockerfile b/ci/containers/fedora-rawhide.Dockerfile index 79bacbcc95..36759c777e 100644 --- a/ci/containers/fedora-rawhide.Dockerfile +++ b/ci/containers/fedora-rawhide.Dockerfile @@ -94,6 +94,7 @@ exec "$@"' > /usr/bin/nosync && \ sanlock-devel \ scrub \ sed \ + selinux-policy-devel \ sheepdog \ systemtap-sdt-devel \ wireshark-devel \ -- 2.31.1

On Fri, Aug 06, 2021 at 06:47:57PM +0100, Daniel P. Berrangé wrote:
This is an extension of
https://listman.redhat.com/archives/libvir-list/2021-July/msg00167.html
The original patches from that series are unchanged apart from the commit message, and tweak to the min fedora version in the RPM.
I then include various refactors/cleanups.
On Fedora 34 I notice the following:
../src/security/selinux/virt.te:579: Warning: fs_rw_anon_inodefs_files(virtd_t) has been deprecated. All calls can be safely removed. ../src/security/selinux/virt.te:580: Warning: fs_list_inotifyfs(virtd_t) has been deprecated. All calls can be safely removed. ../src/security/selinux/virt.te:985: Warning: fs_rw_anon_inodefs_files(virt_domain) has been deprecated. All calls can be safely removed. ../src/security/selinux/virt.te:1520: Warning: fs_list_inotifyfs(svirt_sandbox_domain) has been deprecated. All calls can be safely removed.
assuming those warnings are correct, we can delete a few things from the policy, but that's not done here.
Daniel P. Berrangé (10): selinux: remove redundant use of 'set_variable' function selinux: move selinux policy build helper to scripts directory selinux: don't hardcode paths to selinux tools selinux: don't hardcode policy include files directory rpm: move logic for setting selinux policy variables rpm: rename selinux variables to improve clarity selinux: introduce meson option for selinux policy install selinux: remove duplicate sources list for policy scripts: use variables for cli args in selinux helper scripts: factor repeated path joins from selinux helper
Nikola Knazekova (1): security: add SELinux policy for virt
Vit Mojzis (2): selinux: introduce build, install, packaging for selinux policy Install selinux-policy-devel in test environment
Overall looks reasonable, there are some small issues and we should clarify where the policy comes from and add the missing system.token bits. Pavel
participants (3)
-
Daniel P. Berrangé
-
Pavel Hrdina
-
Vit Mojzis