policy_module(container)

## <desc>
##	<p>
##	Allow containers to manage cgroups.
##	This is required for systemd to run inside
##	containers.
##	</p>
## </desc>
gen_tunable(container_manage_cgroup, false)

## <desc>
##	<p>
##	Allow container engines to mount on all non-security files.
##	</p>
## </desc>
gen_tunable(container_mounton_non_security, false)

## <desc>
##	<p>
##	Allow containers to manage all read-writable public content.
##	</p>
## </desc>
gen_tunable(container_manage_public_content, false)

## <desc>
##	<p>
##	Allow containers to read all public content.
##	</p>
## </desc>
gen_tunable(container_read_public_content, false)

## <desc>
##	<p>
##	Allow super privileged containers to create NFS servers.
##	</p>
## </desc>
gen_tunable(container_spc_create_nfs_servers, false)

## <desc>
##	<p>
##	Allow super privileged containers to use tun-tap devices.
##	</p>
## </desc>
gen_tunable(container_spc_use_tun_tap_dev, false)

## <desc>
##	<p>
##	Allow containers to use direct rendering devices.
##	</p>
## </desc>
gen_tunable(container_use_dri, false)

## <desc>
##	<p>
##	Allow containers to use eCryptfs filesystems.
##	</p>
## </desc>
gen_tunable(container_use_ecryptfs, false)

## <desc>
##	<p>
##	Allow containers to use all capabilities in a
##	non-namespaced context for various privileged operations
##	directly on the host.
##	</p>
## </desc>
gen_tunable(container_use_host_all_caps, false)

## <desc>
##	<p>
##	Allow containers to use huge pages.
##	</p>
## </desc>
gen_tunable(container_use_hugetlbfs, false)

## <desc>
##	<p>
##	Allow containers to use the mknod syscall, e.g. for
##	creating special device files.
##	</p>
## </desc>
gen_tunable(container_use_mknod, false)

## <desc>
##	<p>
##	Allow containers to use NFS filesystems.
##	</p>
## </desc>
gen_tunable(container_use_nfs, false)

## <desc>
##	<p>
##	Allow containers to use CIFS filesystems.
##	</p>
## </desc>
gen_tunable(container_use_samba, false)

## <desc>
##	<p>
##	Allow containers to use the sysadmin capability, e.g.
##	for mounting filesystems.
##	</p>
## </desc>
gen_tunable(container_use_sysadmin, false)

## <desc>
##	<p>
##	Allow containers to use all capabilities in a
##	namespaced context for various privileged operations
##	within the container itself.
##	</p>
## </desc>
gen_tunable(container_use_userns_all_caps, false)

## <desc>
##	<p>
##	Allow containers to use the mknod syscall in a
##	namespaced context, e.g. for creating special device
##	files within the container itself.
##	</p>
## </desc>
gen_tunable(container_use_userns_mknod, false)

## <desc>
##	<p>
##	Allow containers to use the sysadmin capability in a
##	namespaced context, e.g. for mounting filesystems
##	within the container itself.
##	</p>
## </desc>
gen_tunable(container_use_userns_sysadmin, false)

########################################
#
# Declarations
#

# common attribute for all containers
attribute container_domain;

# common attribute for all container engines
attribute container_engine_domain;

# system container engines can only interact with
# system containers, and user container engines
# can only interact with user containers.
attribute container_system_domain;
attribute container_user_domain;
attribute container_engine_system_domain;
attribute container_engine_user_domain;

# containers which require network access
attribute container_net_domain;

# containers considered privileged
attribute privileged_container_domain;

attribute container_engine_exec_type;

attribute container_mountpoint_type;

attribute_role container_roles;
roleattribute system_r container_roles;

container_domain_template(container)
typealias container_t alias svirt_lxc_net_t;
typeattribute container_t container_system_domain, container_user_domain, container_net_domain;
optional_policy(`
	kubernetes_container(container_t)
')

container_engine_domain_template(container_engine)
typeattribute container_engine_t container_engine_system_domain;
type container_engine_exec_t, container_engine_exec_type;
application_domain(container_engine_t, container_engine_exec_t)
init_daemon_domain(container_engine_t, container_engine_exec_t)
ifdef(`enable_mls',`
	init_ranged_daemon_domain(container_engine_t, container_engine_exec_t, s0 - mls_systemhigh)
')
mls_trusted_object(container_engine_t)

type spc_t, container_domain, container_net_domain, container_system_domain, privileged_container_domain;
domain_type(spc_t)
role system_r types spc_t;
optional_policy(`
	kubernetes_container(spc_t)
')

type spc_user_t, container_domain, container_net_domain, container_user_domain, privileged_container_domain;
domain_type(spc_user_t)

type container_engine_unit_t;
init_unit_file(container_engine_unit_t)

type container_unit_t;
init_unit_file(container_unit_t)

type container_config_t;
files_config_file(container_config_t)
optional_policy(`
	kubernetes_mountpoint(container_config_t)
')

type container_var_lib_t;
files_type(container_var_lib_t)
container_mountpoint(container_var_lib_t)

type container_engine_tmp_t;
files_tmp_file(container_engine_tmp_t)
container_mountpoint(container_engine_tmp_t)

type container_engine_tmpfs_t;
files_tmpfs_file(container_engine_tmpfs_t)
container_mountpoint(container_engine_tmpfs_t)

type container_engine_lock_t;
files_lock_file(container_engine_lock_t)

type container_runtime_t;
files_runtime_file(container_runtime_t)
container_mountpoint(container_runtime_t)

type container_tmpfs_t;
files_tmpfs_file(container_tmpfs_t)

type container_log_t;
logging_log_file(container_log_t)
optional_policy(`
	kubernetes_mountpoint(container_log_t)
')

# generic devices created in container /dev filesystems
type container_device_t;
dev_node(container_device_t)

type container_devpts_t;
term_pty(container_devpts_t)

type container_plugin_t;
corecmd_executable_file(container_plugin_t)
optional_policy(`
	kubernetes_mountpoint(container_plugin_t)
')

type container_file_t alias svirt_lxc_file_t;
dev_node(container_file_t)
files_mountpoint(container_file_t)
files_associate_rootfs(container_file_t)
term_pty(container_file_t)
container_mountpoint(container_file_t)
optional_policy(`
	kubernetes_mountpoint(container_file_t)
')

type container_ro_file_t;
files_mountpoint(container_ro_file_t)
container_mountpoint(container_ro_file_t)

type container_engine_cache_t;
files_type(container_engine_cache_t)

type container_cache_home_t;
xdg_cache_content(container_cache_home_t)

type container_conf_home_t;
xdg_config_content(container_conf_home_t)

type container_data_home_t;
xdg_data_content(container_data_home_t)
container_mountpoint(container_data_home_t)

type container_user_runtime_t;
files_runtime_file(container_user_runtime_t)
userdom_user_runtime_content(container_user_runtime_t)
container_mountpoint(container_user_runtime_t)

type container_port_t;
corenet_port(container_port_t)

########################################
#
# Common container domain local policy
#

dontaudit container_domain self:capability fsetid;
dontaudit container_domain self:capability2 block_suspend;
allow container_domain self:cap_userns { chown dac_override dac_read_search fowner kill setgid setuid };
allow container_domain self:process { execmem execstack getattr getcap getsched getsession setcap setpgid setsched signal_perms };
allow container_domain self:dir rw_dir_perms;
allow container_domain self:file create_file_perms;
allow container_domain self:fifo_file manage_fifo_file_perms;
allow container_domain self:sem create_sem_perms;
allow container_domain self:shm create_shm_perms;
allow container_domain self:msgq create_msgq_perms;
allow container_domain self:unix_stream_socket { connectto create_stream_socket_perms };
allow container_domain self:unix_dgram_socket { create_socket_perms sendto };

manage_dirs_pattern(container_domain, container_file_t, container_file_t)
manage_files_pattern(container_domain, container_file_t, container_file_t)
manage_lnk_files_pattern(container_domain, container_file_t, container_file_t)
manage_sock_files_pattern(container_domain, container_file_t, container_file_t)
manage_fifo_files_pattern(container_domain, container_file_t, container_file_t)
rw_chr_files_pattern(container_domain, container_file_t, container_file_t)
rw_blk_files_pattern(container_domain, container_file_t, container_file_t)
allow container_domain container_file_t:dir_file_class_set watch;
allow container_domain container_file_t:file { entrypoint map relabel_file_perms };
allow container_domain container_file_t:chr_file map;

allow container_domain container_ro_file_t:blk_file read_blk_file_perms;
allow container_domain container_ro_file_t:dir list_dir_perms;
allow container_domain container_ro_file_t:chr_file read_chr_file_perms;
allow container_domain container_ro_file_t:file { exec_file_perms read_file_perms };
allow container_domain container_ro_file_t:lnk_file read_lnk_file_perms;
allow container_domain container_ro_file_t:sock_file read_sock_file_perms;

fs_tmpfs_filetrans(container_domain, container_tmpfs_t, { dir file fifo_file lnk_file sock_file })
manage_dirs_pattern(container_domain, container_tmpfs_t, container_tmpfs_t)
mmap_manage_files_pattern(container_domain, container_tmpfs_t, container_tmpfs_t)
mmap_exec_files_pattern(container_domain, container_tmpfs_t, container_tmpfs_t)
manage_fifo_files_pattern(container_domain, container_tmpfs_t, container_tmpfs_t)
manage_lnk_files_pattern(container_domain, container_tmpfs_t, container_tmpfs_t)
manage_sock_files_pattern(container_domain, container_tmpfs_t, container_tmpfs_t)

can_exec(container_domain, container_file_t)
corecmd_watch_bin_dirs(container_domain)

kernel_getattr_proc(container_domain)
kernel_list_all_proc(container_domain)
kernel_associate_proc(container_domain)
kernel_read_kernel_sysctls(container_domain)
kernel_rw_net_sysctls(container_domain)
kernel_read_system_state(container_domain)
kernel_dontaudit_search_kernel_sysctl(container_domain)

corecmd_exec_all_executables(container_domain)

files_dontaudit_getattr_all_dirs(container_domain)
files_dontaudit_getattr_all_files(container_domain)
files_dontaudit_getattr_all_symlinks(container_domain)
files_dontaudit_getattr_all_pipes(container_domain)
files_dontaudit_getattr_all_sockets(container_domain)
files_dontaudit_list_all_mountpoints(container_domain)
files_dontaudit_write_etc_runtime_files(container_domain)
files_list_var(container_domain)
files_list_var_lib(container_domain)
files_search_all(container_domain)
files_read_config_files(container_domain)
files_read_usr_files(container_domain)
files_read_usr_symlinks(container_domain)

fs_getattr_all_fs(container_domain)
fs_list_inotifyfs(container_domain)
# for rootless containers and containers using fusefs mounts
fs_manage_fusefs_dirs(container_domain)
fs_watch_fusefs_dirs(container_t)
fs_manage_fusefs_files(container_domain)
fs_watch_fusefs_files(container_t)
fs_manage_fusefs_chr_files(container_domain)
fs_manage_fusefs_fifo_files(container_domain)
fs_manage_fusefs_sock_files(container_domain)
fs_manage_fusefs_symlinks(container_domain)
fs_exec_fusefs_files(container_domain)
fs_fusefs_entry_type(container_domain)

auth_dontaudit_read_login_records(container_domain)
auth_dontaudit_write_login_records(container_domain)
auth_search_pam_console_data(container_domain)

clock_read_adjtime(container_domain)

init_read_utmp(container_domain)
init_dontaudit_write_utmp(container_domain)
# for podman run --log-driver=passthrough
init_rw_stream_sockets(container_domain)
init_use_fds(container_domain)

libs_dontaudit_setattr_lib_files(container_domain)

miscfiles_read_localization(container_domain)
miscfiles_dontaudit_setattr_fonts_cache_dirs(container_domain)
miscfiles_read_fonts(container_domain)

mta_dontaudit_read_spool_symlinks(container_domain)

container_rw_device_files(container_domain)
container_use_container_ptys(container_domain)

tunable_policy(`container_manage_cgroup',`
	fs_manage_cgroup_dirs(container_domain)
	fs_manage_cgroup_files(container_domain)
')

tunable_policy(`container_manage_public_content',`
	miscfiles_manage_public_files(container_domain)
	miscfiles_watch_public_dirs(container_domain)
')
optional_policy(`
	# range_transition is not valid in a tunable
	miscfiles_rangetrans_all_public_content(container_domain, s0)
')

tunable_policy(`container_read_public_content',`
	miscfiles_read_public_files(container_domain)
	miscfiles_watch_public_dirs(container_domain)
')

tunable_policy(`container_use_dri',`
	dev_rw_dri(container_domain)
')

tunable_policy(`container_use_ecryptfs',`
	fs_manage_ecryptfs_dirs(container_domain)
	fs_manage_ecryptfs_files(container_domain)
	fs_manage_ecryptfs_named_sockets(container_domain)
	fs_list_ecryptfs(container_domain)
')

tunable_policy(`container_use_hugetlbfs',`
	fs_mmap_rw_hugetlbfs_files(container_t)
')

tunable_policy(`container_use_nfs',`
	fs_manage_nfs_dirs(container_domain)
	fs_manage_nfs_files(container_domain)
	fs_manage_nfs_named_sockets(container_domain)
	fs_read_nfs_symlinks(container_domain)
	fs_exec_nfs_files(container_domain)
	fs_watch_nfs_dirs(container_domain)
	fs_watch_nfs_files(container_domain)
')

tunable_policy(`container_use_samba',`
	fs_manage_cifs_dirs(container_domain)
	fs_manage_cifs_files(container_domain)
	fs_manage_cifs_named_sockets(container_domain)
	fs_read_cifs_symlinks(container_domain)
	fs_exec_cifs_files(container_domain)
')

optional_policy(`
	kubernetes_list_tmpfs(container_domain)
	kubernetes_read_tmpfs_files(container_domain)
	kubernetes_read_tmpfs_symlinks(container_domain)
	kubernetes_watch_tmpfs_dirs(container_domain)
	kubernetes_watch_tmpfs_files(container_domain)
')

optional_policy(`
	podman_rw_conmon_pipes(container_domain)
	podman_use_conmon_fds(container_domain)
')

optional_policy(`
	udev_read_runtime_files(container_domain)
')

optional_policy(`
	apache_exec_modules(container_domain)
	apache_read_sys_content(container_domain)
')

optional_policy(`
	virt_lxc_use_fds(container_domain)
	virt_lxc_rw_pipes(container_domain)
	virt_lxc_sigchld(container_domain)
	virt_lxc_stream_connect(container_domain)
	virt_lxc_list_runtime(container_domain)
	virt_lxc_read_runtime(container_domain)
	virt_virsh_use_fds(container_domain)
	virt_virsh_rw_pipes(container_domain)
	virt_virsh_sigchld(container_domain)
')

########################################
#
# Common container system domain local policy
#

optional_policy(`
	kubernetes_read_container_engine_state(container_system_domain)
')

########################################
#
# Common container net domain local policy
#

allow container_net_domain self:cap_userns { net_admin net_bind_service net_raw };
allow container_net_domain self:tcp_socket create_stream_socket_perms;
allow container_net_domain self:udp_socket create_socket_perms;
allow container_net_domain self:tun_socket create_socket_perms;
allow container_net_domain self:packet_socket create_socket_perms;
allow container_net_domain self:socket create_socket_perms;
allow container_net_domain self:icmp_socket create_socket_perms;
allow container_net_domain self:rawip_socket create_socket_perms;
allow container_net_domain self:netlink_route_socket create_netlink_socket_perms;
allow container_net_domain self:netlink_socket create_socket_perms;
allow container_net_domain self:netlink_tcpdiag_socket create_socket_perms;
allow container_net_domain self:netlink_kobject_uevent_socket create_socket_perms;

corenet_all_recvfrom_netlabel(container_net_domain)
corenet_tcp_sendrecv_generic_if(container_net_domain)
corenet_udp_sendrecv_generic_if(container_net_domain)
corenet_tcp_sendrecv_generic_node(container_net_domain)
corenet_udp_sendrecv_generic_node(container_net_domain)
corenet_tcp_bind_generic_node(container_net_domain)
corenet_udp_bind_generic_node(container_net_domain)
# for metallb BGP speakers
corenet_raw_bind_generic_node(container_net_domain)

corenet_sendrecv_all_server_packets(container_net_domain)
corenet_tcp_bind_all_ports(container_net_domain)
corenet_udp_bind_all_ports(container_net_domain)

corenet_sendrecv_all_client_packets(container_net_domain)
corenet_tcp_connect_all_ports(container_net_domain)

########################################
#
# Container local policy
#

allow container_t self:process { getcap setrlimit };

allow container_t container_file_t:filesystem getattr;

kernel_read_network_state(container_t)
kernel_read_irq_sysctls(container_t)

dev_getattr_mtrr_dev(container_t)
dev_read_rand(container_t)
dev_read_sysfs(container_t)
dev_read_urand(container_t)

files_read_kernel_modules(container_t)

fs_mount_cgroup(container_t)
fs_rw_cgroup_files(container_t)
# for metallb BGP speakers
fs_read_nsfs_files(container_t)

kernel_get_sysvipc_info(container_t)
kernel_read_fs_sysctls(container_t)
kernel_read_vm_overcommit_sysctl(container_t)

auth_use_nsswitch(container_t)

logging_send_audit_msgs(container_t)

userdom_use_user_ptys(container_t)

tunable_policy(`container_use_host_all_caps',`
	# omitted sys_module
	allow container_t self:capability { audit_control audit_write chown dac_override dac_read_search fowner fsetid ipc_lock ipc_owner kill lease linux_immutable mknod net_admin net_bind_service net_broadcast net_raw setfcap setgid setpcap setuid sys_admin sys_boot sys_chroot sys_nice sys_pacct sys_ptrace sys_rawio sys_resource sys_time sys_tty_config };
	# omitted mac_admin, mac_override
	allow container_t self:capability2 { audit_read block_suspend bpf checkpoint_restore perfmon syslog wake_alarm };
')

tunable_policy(`container_use_mknod',`
	allow container_t self:capability mknod;
')

tunable_policy(`container_use_sysadmin',`
	allow container_t self:capability sys_admin;
')

tunable_policy(`container_use_userns_all_caps',`
	# omitted sys_module
	allow container_t self:cap_userns { audit_control audit_write chown dac_override dac_read_search fowner fsetid ipc_lock ipc_owner kill lease linux_immutable mknod net_admin net_bind_service net_broadcast net_raw setfcap setgid setpcap setuid sys_admin sys_boot sys_chroot sys_nice sys_pacct sys_ptrace sys_rawio sys_resource sys_time sys_tty_config };
	# omitted mac_admin, mac_override
	allow container_t self:cap2_userns { audit_read block_suspend bpf checkpoint_restore perfmon syslog wake_alarm };
')

tunable_policy(`container_use_userns_mknod || container_use_mknod',`
	allow container_t self:cap_userns mknod;
')

tunable_policy(`container_use_userns_sysadmin || container_use_sysadmin',`
	allow container_t self:cap_userns sys_admin;
')

optional_policy(`
	rpm_read_db(container_t)
')

########################################
#
# Common container engine local policy
#

allow container_engine_domain self:process { fork getcap getrlimit getsched noatsecure rlimitinh setcap setexec setkeycreate setpgid setrlimit setsched siginh signal_perms transition };
allow container_engine_domain self:capability { chown dac_override dac_read_search fowner fsetid kill mknod net_admin net_raw setfcap setgid setpcap setuid sys_admin sys_chroot sys_ptrace sys_resource };
allow container_engine_domain self:capability2 { bpf perfmon };
allow container_engine_domain self:bpf { map_create map_read map_write prog_load prog_run };
allow container_engine_domain self:cap_userns { audit_write chown dac_override dac_read_search fowner fsetid ipc_lock ipc_owner kill lease linux_immutable mknod net_admin net_bind_service net_raw setfcap setgid setpcap setuid sys_admin sys_boot sys_chroot sys_nice sys_pacct sys_ptrace sys_rawio sys_resource sys_time sys_tty_config };
allow container_engine_domain self:cap2_userns { audit_read block_suspend bpf perfmon syslog wake_alarm };
allow container_engine_domain self:bpf { map_create map_read map_write prog_load prog_run };
allow container_engine_domain self:fd use;
allow container_engine_domain self:user_namespace create;
allow container_engine_domain self:fifo_file manage_fifo_file_perms;
allow container_engine_domain self:tcp_socket create_stream_socket_perms;
allow container_engine_domain self:udp_socket create_socket_perms;
allow container_engine_domain self:unix_stream_socket { connectto create_stream_socket_perms };
allow container_engine_domain self:unix_dgram_socket { create_socket_perms sendto };
allow container_engine_domain self:icmp_socket create_socket_perms;
allow container_engine_domain self:netlink_route_socket create_netlink_socket_perms;
allow container_engine_domain self:packet_socket create_socket_perms;

allow container_engine_domain container_devpts_t:chr_file { rw_chr_file_perms setattr };
term_create_pty(container_engine_domain, container_devpts_t)

allow container_engine_domain container_port_t:tcp_socket name_bind;

dontaudit container_engine_domain container_domain:process { noatsecure rlimitinh siginh };
allow container_engine_domain container_domain:process2 { nnp_transition nosuid_transition };

allow container_engine_domain container_mountpoint_type:dir list_dir_perms;
allow container_engine_domain container_mountpoint_type:dir_file_class_set { getattr mounton };

corecmd_bin_entry_type(container_engine_domain)
corecmd_exec_bin(container_engine_domain)
# needed when spawning interactive shells inside containers
corecmd_exec_shell(container_engine_domain)
corecmd_search_bin(container_engine_domain)
# podman unshare causes most of this noise
corecmd_dontaudit_exec_all_executables(container_engine_domain)

corenet_tcp_bind_generic_node(container_engine_domain)
corenet_tcp_connect_http_port(container_engine_domain)
corenet_tcp_connect_http_cache_port(container_engine_domain)
corenet_tcp_bind_all_ports(container_engine_domain)
corenet_udp_bind_generic_node(container_engine_domain)
corenet_udp_bind_all_ports(container_engine_domain)
corenet_rw_tun_tap_dev(container_engine_domain)

dev_getattr_all_blk_files(container_engine_domain)
dev_getattr_all_chr_files(container_engine_domain)
dev_getattr_generic_blk_files(container_engine_domain)
dev_getattr_generic_chr_files(container_engine_domain)
dev_setattr_null_dev(container_engine_domain)
dev_getattr_fs(container_engine_domain)
dev_remount_fs(container_engine_domain)
dev_list_sysfs(container_engine_domain)
# required by crun
dev_read_sysfs(container_engine_domain)
dev_mount_sysfs(container_engine_domain)
dev_remount_sysfs(container_engine_domain)
dev_mounton_sysfs_dirs(container_engine_domain)

domain_use_interactive_fds(container_engine_domain)
# podman unshare causes most of this noise
domain_dontaudit_search_all_domains_state(container_engine_domain)

files_read_etc_files(container_engine_domain)
files_read_usr_files(container_engine_domain)
files_mounton_root(container_engine_domain)
files_mounton_tmp(container_engine_domain)
files_dontaudit_getattr_all_dirs(container_engine_domain)
files_dontaudit_getattr_all_files(container_engine_domain)

fs_getattr_nsfs(container_engine_domain)
fs_read_nsfs_files(container_engine_domain)
fs_unmount_nsfs(container_engine_domain)

fs_getattr_tmpfs(container_engine_domain)
fs_mount_tmpfs(container_engine_domain)
fs_remount_tmpfs(container_engine_domain)
fs_unmount_tmpfs(container_engine_domain)
fs_relabelfrom_tmpfs(container_engine_domain)

fs_getattr_xattr_fs(container_engine_domain)
fs_mount_xattr_fs(container_engine_domain)
fs_remount_xattr_fs(container_engine_domain)
fs_unmount_xattr_fs(container_engine_domain)
fs_relabelfrom_xattr_fs(container_engine_domain)
fs_get_xattr_fs_quotas(container_engine_domain)

fs_getattr_cgroup(container_engine_domain)
fs_manage_cgroup_dirs(container_engine_domain)
fs_manage_cgroup_files(container_engine_domain)
fs_watch_cgroup_files(container_engine_domain)
fs_mount_cgroup(container_engine_domain)
fs_remount_cgroup(container_engine_domain)
fs_mounton_cgroup(container_engine_domain)
fs_read_cgroup_symlinks(container_engine_domain)

fs_getattr_fusefs(container_engine_domain)
fs_remount_fusefs(container_engine_domain)

fs_list_hugetlbfs(container_engine_domain)

kernel_getattr_proc(container_engine_domain)
kernel_mount_proc(container_engine_domain)
kernel_remount_proc(container_engine_domain)
kernel_read_kernel_sysctls(container_engine_domain)
kernel_read_network_state(container_engine_domain)
kernel_read_system_state(container_engine_domain)
kernel_rw_net_sysctls(container_engine_domain)
kernel_dontaudit_search_kernel_sysctl(container_engine_domain)
kernel_getattr_core_if(container_engine_domain)

selinux_get_fs_mount(container_engine_domain)
selinux_mount_fs(container_engine_domain)
selinux_remount_fs(container_engine_domain)
selinux_unmount_fs(container_engine_domain)
seutil_read_config(container_engine_domain)
seutil_read_default_contexts(container_engine_domain)

term_mount_devpts(container_engine_domain)
term_relabel_pty_fs(container_engine_domain)

init_read_state(container_engine_domain)

miscfiles_read_generic_certs(container_engine_domain)
miscfiles_read_localization(container_engine_domain)
miscfiles_dontaudit_setattr_fonts_cache_dirs(container_engine_domain)

modutils_domtrans(container_engine_domain)

sysnet_exec_ifconfig(container_engine_domain)
sysnet_create_netns_dirs(container_engine_domain)
# nsfs mountpoints get created in /run/netns, which
# will be labeled nsfs_t once bind-mounted
sysnet_netns_filetrans(container_engine_domain, container_runtime_t, file)

userdom_use_user_ptys(container_engine_domain)

can_exec(container_engine_domain, container_engine_exec_type)

list_dirs_pattern(container_engine_domain, container_config_t, container_config_t)
read_files_pattern(container_engine_domain, container_config_t, container_config_t)
read_lnk_files_pattern(container_engine_domain, container_config_t, container_config_t)
allow container_engine_domain container_config_t:{ dir file } watch;

allow container_engine_domain container_engine_tmp_t:dir manage_dir_perms;
allow container_engine_domain container_engine_tmp_t:file manage_file_perms;
allow container_engine_domain container_engine_tmp_t:fifo_file manage_fifo_file_perms;
# podman uses temporary symlinks when loading container images
allow container_engine_domain container_engine_tmp_t:lnk_file manage_lnk_file_perms;
# needed when manually spawning processes inside containers
allow container_engine_domain container_engine_tmp_t:sock_file manage_sock_file_perms;
files_tmp_filetrans(container_engine_domain, container_engine_tmp_t, { dir file sock_file })

allow container_engine_domain container_engine_tmpfs_t:dir { manage_dir_perms relabel_dir_perms };
allow container_engine_domain container_engine_tmpfs_t:file { exec_file_perms manage_file_perms relabel_file_perms };
allow container_engine_domain container_engine_tmpfs_t:blk_file { manage_blk_file_perms relabel_blk_file_perms };
allow container_engine_domain container_engine_tmpfs_t:chr_file { manage_chr_file_perms relabel_chr_file_perms };
allow container_engine_domain container_engine_tmpfs_t:lnk_file { manage_lnk_file_perms relabel_lnk_file_perms };
allow container_engine_domain container_engine_tmpfs_t:sock_file { manage_sock_file_perms relabel_sock_file_perms };
fs_tmpfs_filetrans(container_engine_domain, container_engine_tmpfs_t, { dir file })

manage_dirs_pattern(container_engine_domain, container_engine_lock_t, container_engine_lock_t)
manage_files_pattern(container_engine_domain, container_engine_lock_t, container_engine_lock_t)
files_lock_filetrans(container_engine_domain, container_engine_lock_t, { dir file })

allow container_engine_domain container_file_t:dir { manage_dir_perms relabel_dir_perms };
allow container_engine_domain container_file_t:file { exec_file_perms manage_file_perms relabel_file_perms };
allow container_engine_domain container_file_t:blk_file { manage_blk_file_perms relabel_blk_file_perms };
allow container_engine_domain container_file_t:chr_file { manage_chr_file_perms relabel_chr_file_perms };
allow container_engine_domain container_file_t:fifo_file { manage_fifo_file_perms relabel_fifo_file_perms };
allow container_engine_domain container_file_t:lnk_file { manage_lnk_file_perms relabel_lnk_file_perms };
allow container_engine_domain container_file_t:sock_file { manage_sock_file_perms relabel_sock_file_perms };
allow container_engine_domain container_file_t:filesystem { getattr mount relabelfrom relabelto remount unmount };

allow container_engine_domain container_ro_file_t:dir { manage_dir_perms relabel_dir_perms };
allow container_engine_domain container_ro_file_t:file { exec_file_perms manage_file_perms relabel_file_perms };
allow container_engine_domain container_ro_file_t:blk_file { manage_blk_file_perms relabel_blk_file_perms };
allow container_engine_domain container_ro_file_t:chr_file { manage_chr_file_perms relabel_chr_file_perms };
allow container_engine_domain container_ro_file_t:fifo_file { manage_fifo_file_perms relabel_fifo_file_perms };
allow container_engine_domain container_ro_file_t:lnk_file { manage_lnk_file_perms relabel_lnk_file_perms };
allow container_engine_domain container_ro_file_t:sock_file { manage_sock_file_perms relabel_sock_file_perms };

ifdef(`init_systemd',`
	# needed by runc, which is also invoked by other engines
	init_run_bpf(container_engine_domain)
')

tunable_policy(`container_manage_public_content',`
	miscfiles_read_public_files(container_engine_domain)
')

tunable_policy(`container_read_public_content',`
	miscfiles_read_public_files(container_engine_domain)
')

tunable_policy(`container_mounton_non_security',`
	files_mounton_non_security(container_engine_domain)
')

tunable_policy(`container_use_nfs',`
	fs_manage_nfs_dirs(container_engine_domain)
	fs_manage_nfs_files(container_engine_domain)
	fs_manage_nfs_named_sockets(container_engine_domain)
	fs_read_nfs_symlinks(container_engine_domain)
	fs_mount_nfs(container_engine_domain)
	fs_unmount_nfs(container_engine_domain)
	fs_mounton_nfs(container_engine_domain)
	fs_exec_nfs_files(container_engine_domain)
	kernel_rw_fs_sysctls(container_engine_domain)
',`
	kernel_dontaudit_search_fs_sysctls(container_engine_domain)
')

tunable_policy(`container_use_samba',`
	fs_manage_cifs_dirs(container_engine_domain)
	fs_manage_cifs_files(container_engine_domain)
	fs_manage_cifs_named_sockets(container_engine_domain)
	fs_read_cifs_symlinks(container_engine_domain)
	fs_exec_cifs_files(container_engine_domain)
')

optional_policy(`
	# to verify container image signatures
	gpg_exec(container_engine_domain)
	gpg_dontaudit_exec_agent(container_engine_domain)
	gpg_dontaudit_search_user_secrets(container_engine_domain)
')

optional_policy(`
	iptables_domtrans(container_engine_domain)
')

########################################
#
# Common system container engine local policy
#

allow container_engine_system_domain container_domain:process { sigkill signal signull transition };
allow container_engine_system_domain container_domain:key { create search setattr view };

ps_process_pattern(container_engine_system_domain, container_system_domain)
allow container_system_domain container_engine_system_domain:fd use;
allow container_system_domain container_engine_system_domain:fifo_file rw_fifo_file_perms;

# for managing container storage on ZFS volumes
fstools_exec(container_engine_system_domain)

logging_send_syslog_msg(container_engine_system_domain)

create_dirs_pattern(container_engine_system_domain, container_config_t, container_config_t)
files_etc_filetrans(container_engine_system_domain, container_config_t, dir)

manage_dirs_pattern(container_engine_system_domain, container_log_t, container_log_t)
manage_files_pattern(container_engine_system_domain, container_log_t, container_log_t)
logging_log_filetrans(container_engine_system_domain, container_log_t, { dir file })

allow container_engine_system_domain container_var_lib_t:dir { manage_dir_perms relabel_dir_perms watch };
allow container_engine_system_domain container_var_lib_t:file { exec_file_perms manage_file_perms relabel_file_perms };
allow container_engine_system_domain container_var_lib_t:blk_file { manage_blk_file_perms relabel_blk_file_perms };
allow container_engine_system_domain container_var_lib_t:chr_file { manage_chr_file_perms relabel_chr_file_perms };
allow container_engine_system_domain container_var_lib_t:fifo_file { manage_fifo_file_perms relabel_fifo_file_perms };
allow container_engine_system_domain container_var_lib_t:lnk_file { manage_lnk_file_perms relabel_lnk_file_perms };
allow container_engine_system_domain container_var_lib_t:sock_file { manage_sock_file_perms relabel_sock_file_perms };
files_var_lib_filetrans(container_engine_system_domain, container_var_lib_t, dir)
filetrans_pattern(container_engine_system_domain, container_var_lib_t, container_ro_file_t, file, "config.env")
filetrans_pattern(container_engine_system_domain, container_var_lib_t, container_ro_file_t, file, "hosts")
filetrans_pattern(container_engine_system_domain, container_var_lib_t, container_ro_file_t, file, "hostname")
filetrans_pattern(container_engine_system_domain, container_var_lib_t, container_ro_file_t, file, "resolv.conf")
filetrans_pattern(container_engine_system_domain, container_var_lib_t, container_ro_file_t, dir, "init")
filetrans_pattern(container_engine_system_domain, container_var_lib_t, container_ro_file_t, dir, "overlay")
filetrans_pattern(container_engine_system_domain, container_var_lib_t, container_ro_file_t, dir, "overlay-images")
filetrans_pattern(container_engine_system_domain, container_var_lib_t, container_ro_file_t, dir, "overlay-layers")
filetrans_pattern(container_engine_system_domain, container_var_lib_t, container_ro_file_t, dir, "overlay2")
filetrans_pattern(container_engine_system_domain, container_var_lib_t, container_ro_file_t, dir, "overlay2-images")
filetrans_pattern(container_engine_system_domain, container_var_lib_t, container_ro_file_t, dir, "overlay2-layers")
filetrans_pattern(container_engine_system_domain, container_var_lib_t, container_file_t, dir, "volumes")

allow container_engine_system_domain container_runtime_t:dir { manage_dir_perms relabel_dir_perms watch };
allow container_engine_system_domain container_runtime_t:file { mmap_manage_file_perms relabel_file_perms watch };
allow container_engine_system_domain container_runtime_t:fifo_file { manage_fifo_file_perms relabel_fifo_file_perms };
allow container_engine_system_domain container_runtime_t:lnk_file { manage_lnk_file_perms relabel_lnk_file_perms };
allow container_engine_system_domain container_runtime_t:sock_file { manage_sock_file_perms relabel_sock_file_perms };
files_runtime_filetrans(container_engine_system_domain, container_runtime_t, { dir file sock_file })

allow container_engine_system_domain container_engine_cache_t:dir manage_dir_perms;
allow container_engine_system_domain container_engine_cache_t:file manage_file_perms;
files_var_filetrans(container_engine_system_domain, container_engine_cache_t, { dir file })

container_exec_plugins(container_engine_system_domain)
container_watch_plugin_dirs(container_engine_system_domain)

optional_policy(`
	zfs_domtrans(container_engine_system_domain)
')

########################################
#
# Common user container engine local policy
#

allow container_engine_user_domain self:tun_socket create_socket_perms;

allow container_engine_user_domain container_user_domain:process { sigkill signal signull transition };
allow container_engine_user_domain container_user_domain:key { create search setattr view };

ps_process_pattern(container_engine_user_domain, container_user_domain)
allow container_user_domain container_engine_user_domain:fd use;
allow container_user_domain container_engine_user_domain:fifo_file rw_fifo_file_perms;

userdom_list_user_home_content(container_engine_user_domain)

xdg_search_config_dirs(container_engine_user_domain)

allow container_engine_user_domain container_user_runtime_t:dir { manage_dir_perms relabel_dir_perms watch };
allow container_engine_user_domain container_user_runtime_t:file { manage_file_perms relabel_file_perms watch };
allow container_engine_user_domain container_user_runtime_t:fifo_file { manage_fifo_file_perms relabel_fifo_file_perms };
allow container_engine_user_domain container_user_runtime_t:lnk_file { manage_lnk_file_perms relabel_lnk_file_perms };
allow container_engine_user_domain container_user_runtime_t:sock_file { manage_sock_file_perms relabel_sock_file_perms };
# file and sock_file filetrans to support rootless docker
userdom_user_runtime_filetrans(container_engine_user_domain, container_user_runtime_t, { dir file sock_file })

allow container_engine_user_domain container_cache_home_t:dir manage_dir_perms;
allow container_engine_user_domain container_cache_home_t:file manage_file_perms;
xdg_cache_filetrans(container_engine_user_domain, container_cache_home_t, dir)

allow container_engine_user_domain container_conf_home_t:dir manage_dir_perms;
allow container_engine_user_domain container_conf_home_t:file manage_file_perms;
xdg_config_filetrans(container_engine_user_domain, container_conf_home_t, dir)

allow container_engine_user_domain container_data_home_t:dir { manage_dir_perms relabel_dir_perms watch };
allow container_engine_user_domain container_data_home_t:file { exec_file_perms manage_file_perms relabel_file_perms };
allow container_engine_user_domain container_data_home_t:chr_file { manage_chr_file_perms relabel_chr_file_perms };
allow container_engine_user_domain container_data_home_t:fifo_file { manage_fifo_file_perms relabel_fifo_file_perms };
allow container_engine_user_domain container_data_home_t:lnk_file { manage_lnk_file_perms relabel_lnk_file_perms };
allow container_engine_user_domain container_data_home_t:sock_file { manage_sock_file_perms relabel_sock_file_perms };
xdg_data_filetrans(container_engine_user_domain, container_data_home_t, dir)
filetrans_pattern(container_engine_user_domain, container_data_home_t, container_ro_file_t, file, "config.env")
filetrans_pattern(container_engine_user_domain, container_data_home_t, container_ro_file_t, file, "hosts")
filetrans_pattern(container_engine_user_domain, container_data_home_t, container_ro_file_t, file, "resolv.conf")
filetrans_pattern(container_engine_user_domain, container_data_home_t, container_ro_file_t, file, "hostname")
filetrans_pattern(container_engine_user_domain, container_data_home_t, container_ro_file_t, dir, "init")
filetrans_pattern(container_engine_user_domain, container_data_home_t, container_ro_file_t, dir, "fuse-overlayfs")
filetrans_pattern(container_engine_user_domain, container_data_home_t, container_ro_file_t, dir, "overlay")
filetrans_pattern(container_engine_user_domain, container_data_home_t, container_ro_file_t, dir, "overlay-images")
filetrans_pattern(container_engine_user_domain, container_data_home_t, container_ro_file_t, dir, "overlay-layers")
filetrans_pattern(container_engine_user_domain, container_data_home_t, container_ro_file_t, dir, "overlay2")
filetrans_pattern(container_engine_user_domain, container_data_home_t, container_ro_file_t, dir, "overlay2-images")
filetrans_pattern(container_engine_user_domain, container_data_home_t, container_ro_file_t, dir, "overlay2-layers")
filetrans_pattern(container_engine_user_domain, container_data_home_t, container_file_t, dir, "volumes")

########################################
#
# Common privileged container local policy
#

allow privileged_container_domain container_file_t:file entrypoint;
allow privileged_container_domain container_ro_file_t:file entrypoint;
allow privileged_container_domain container_var_lib_t:file entrypoint;

optional_policy(`
	systemd_dbus_chat_machined(privileged_container_domain)
	systemd_dbus_chat_logind(privileged_container_domain)
')

########################################
#
# spc local policy
#
# spc_t is the default type for containers created
# with the --privileged (or similar) argument
#

# Containers run from an engine with the --privileged argument are not
# restricted by the engine. One of these restrictions is a manual
# transition to the default context for containers, usually container_t.
# Instead of performing a manual transition when creating a restricted
# container (default), we do an automatic transition to spc_t when
# restrictions are disabled.
domtrans_pattern(container_engine_system_domain, container_file_t, spc_t)
domtrans_pattern(container_engine_system_domain, container_ro_file_t, spc_t)
domtrans_pattern(container_engine_system_domain, container_var_lib_t, spc_t)

allow spc_t self:process { getcap setrlimit };
# Normally triggered when rook-ceph executes lvm tools which creates noise.
# This can be allowed if actually needed.
dontaudit spc_t self:process setfscreate;
allow spc_t self:capability { audit_write chown dac_read_search fowner fsetid ipc_lock mknod net_admin net_raw setpcap sys_admin sys_chroot sys_nice sys_ptrace sys_rawio sys_resource };
allow spc_t self:capability2 { bpf perfmon };
allow spc_t self:bpf { map_create map_read map_write prog_load prog_run };
allow spc_t self:key manage_key_perms;
allow spc_t self:alg_socket create_stream_socket_perms;
allow spc_t self:netlink_audit_socket { create_netlink_socket_perms nlmsg_relay };
allow spc_t self:netlink_generic_socket create_socket_perms;
allow spc_t self:netlink_netfilter_socket create_socket_perms;
allow spc_t self:netlink_tcpdiag_socket nlmsg_read;
allow spc_t self:netlink_xfrm_socket create_netlink_socket_perms;
allow spc_t self:perf_event { cpu kernel open read };

allow container_engine_system_domain spc_t:process { setsched signal_perms };

allow spc_t container_engine_system_domain:fifo_file rw_fifo_file_perms;

# for kubernetes debug pods - for some reason,
# cri-o does not relabel the container's /dev
# when a debug pod is created, so the user will
# be unable to attach to its terminal unless
# this is allowed
allow spc_t container_engine_tmpfs_t:dir list_dir_perms;
allow spc_t container_engine_tmpfs_t:chr_file rw_chr_file_perms;
allow spc_t container_engine_tmpfs_t:lnk_file read_lnk_file_perms;
# for rook-ceph
allow spc_t container_engine_tmpfs_t:blk_file rw_blk_file_perms;

# for kubernetes storage class providers
allow spc_t container_file_t:{ dir file } mounton;
allow spc_t container_file_t:dir_file_class_set relabel_blk_file_perms;
# for rook-ceph
allow spc_t container_file_t:blk_file manage_blk_file_perms;

allow spc_t container_runtime_t:dir { manage_dir_perms mounton };
allow spc_t container_runtime_t:file manage_file_perms;
allow spc_t container_runtime_t:sock_file manage_sock_file_perms;

# for rook-ceph
allow spc_t container_device_t:file manage_file_perms;
allow spc_t container_device_t:blk_file { manage_blk_file_perms relabel_blk_file_perms };
fs_tmpfs_filetrans(spc_t, container_device_t, blk_file)

dev_read_rand(spc_t)
dev_mount_sysfs(spc_t)
dev_unmount_sysfs(spc_t)
dev_remount_sysfs(spc_t)
dev_mounton_sysfs_dirs(spc_t)
dev_read_sysfs(spc_t)
# for rook-ceph
dev_rw_lvm_control(spc_t)
dev_rw_generic_blk_files(spc_t)
dev_write_sysfs(spc_t)
dev_filetrans(spc_t, container_device_t, blk_file)
dev_dontaudit_getattr_all_chr_files(spc_t)
dev_dontaudit_setattr_generic_symlinks(spc_t)
dev_dontaudit_relabelto_generic_blk_files(spc_t)

fs_read_nsfs_files(spc_t)
fs_mount_xattr_fs(spc_t)
fs_unmount_xattr_fs(spc_t)
fs_remount_xattr_fs(spc_t)
fs_mount_cgroup(spc_t)
fs_mounton_cgroup(spc_t)
fs_manage_cgroup_dirs(spc_t)
fs_manage_cgroup_files(spc_t)
fs_mount_bpf(spc_t)
fs_create_bpf_dirs(spc_t)
fs_manage_bpf_files(spc_t)
fs_manage_bpf_symlinks(spc_t)
fs_mounton_fusefs(spc_t)
fs_mounton_fusefs_files(spc_t)
fs_unmount_nsfs(spc_t)
fs_mount_tmpfs(spc_t)
fs_list_tmpfs(spc_t)
fs_watch_tmpfs_dirs(spc_t)
fs_create_fusefs_blk_files(spc_t)
fs_setattr_fusefs_blk_files(spc_t)

kernel_get_sysvipc_info(spc_t)
kernel_load_module(spc_t)
kernel_request_load_module(spc_t)
kernel_read_network_state(spc_t)
kernel_read_vm_overcommit_sysctl(spc_t)
kernel_rw_kernel_sysctl(spc_t)
kernel_dontaudit_list_unlabeled(spc_t)
# for rook-ceph when provisioning volumes
kernel_read_state(spc_t)
kernel_setsched(spc_t)
kernel_getattr_unlabeled_dirs(spc_t)

storage_raw_rw_fixed_disk(spc_t)

files_manage_etc_files(spc_t)

init_read_state(spc_t)
init_write_runtime_socket(spc_t)

iptables_read_runtime_files(spc_t)

# rook-ceph enumerates LVM devices
lvm_read_config(spc_t)
lvm_manage_lock_files(spc_t)
lvm_manage_runtime_files(spc_t)

modutils_read_module_deps(spc_t)

mount_manage_runtime_files(spc_t)

# for kubernetes debug pods
term_use_generic_ptys(spc_t)

container_read_all_container_state(spc_t)

container_manage_config_files(spc_t)

container_list_plugin_dirs(spc_t)
container_manage_plugin_files(spc_t)

container_create_config_files(spc_t)
container_rw_config_files(spc_t)

container_list_log_dirs(spc_t)
container_create_log_dirs(spc_t)
container_manage_log_files(spc_t)

container_manage_var_lib_dirs(spc_t)
container_manage_var_lib_files(spc_t)
container_map_var_lib_files(spc_t)

# for cilium
allow spc_t container_config_t:dir watch;
allow spc_t container_runtime_t:lnk_file manage_lnk_file_perms;
allow spc_t container_runtime_t:file watch;

ifdef(`init_systemd',`
	init_dbus_chat(spc_t)
	init_run_bpf(spc_t)
')

tunable_policy(`container_spc_use_tun_tap_dev',`
	corenet_rw_tun_tap_dev(spc_t)
')

optional_policy(`
	tunable_policy(`container_spc_create_nfs_servers',`
		fs_mount_nfsd_fs(spc_t)
		fs_rw_nfsd_fs(spc_t)
		kernel_mounton_proc_dirs(spc_t)
		kernel_rw_rpc_sysctls(spc_t)
		kernel_rw_fs_sysctls(spc_t)
		rpc_manage_nfs_state_data(spc_t)
	')
')

optional_policy(`
	dbus_system_bus_client(spc_t)
	dbus_all_session_bus_client(spc_t)
')

optional_policy(`
	# various kubernetes control plane pods run as privileged containers
	kubernetes_watch_config_dirs(spc_t)
	kubernetes_watch_config_files(spc_t)
	kubernetes_list_plugins(spc_t)
	kubernetes_watch_plugin_dirs(spc_t)
	kubernetes_manage_plugin_files(spc_t)

	# Calico runs as a privileged container
	kubernetes_run_engine_bpf(spc_t)

	# for device plugins
	kubernetes_stream_connect_kubelet(spc_t)

	# for cilium
	kubernetes_manage_runtime_dirs(spc_t)
	kubernetes_mounton_runtime_dirs(spc_t)
	kubernetes_manage_runtime_files(spc_t)
	kubernetes_map_runtime_files(spc_t)
	kubernetes_watch_runtime_files(spc_t)
	kubernetes_manage_runtime_symlinks(spc_t)
	kubernetes_manage_runtime_sock_files(spc_t)

	# for rook-ceph
	kubernetes_dontaudit_search_engine_keys(spc_t)
')

optional_policy(`
	# If unconfined domains are enabled, spc is also unconfined
	unconfined_domain_noaudit(spc_t)
	domain_ptrace_all_domains(spc_t)
')

########################################
#
# spc user local policy
#

# Similar to above, automatically transition to spc_user_t when a
# container engine runs a container with the --privileged argument
domtrans_pattern(container_engine_user_domain, container_file_t, spc_user_t)
domtrans_pattern(container_engine_user_domain, container_ro_file_t, spc_user_t)
domtrans_pattern(container_engine_user_domain, container_var_lib_t, spc_user_t)
fs_fusefs_domtrans(container_engine_user_domain, spc_user_t)

allow container_engine_user_domain spc_user_t:process { setsched signal_perms };

allow spc_user_t container_engine_user_domain:fifo_file rw_fifo_file_perms;

optional_policy(`
       dbus_system_bus_client(spc_user_t)
       dbus_all_session_bus_client(spc_user_t)
')

optional_policy(`
       # If unconfined domains are enabled, spc is also unconfined
       unconfined_domain_noaudit(spc_user_t)
       domain_ptrace_all_domains(spc_user_t)
')
