From 5105a4c344c0c63022e345154343ab14fe8ee61b Mon Sep 17 00:00:00 2001 From: Kenton Groombridge Date: Tue, 11 Jan 2022 14:15:24 -0500 Subject: [PATCH] container, docker, rootlesskit: add support for rootless docker Rootless docker runs as root in a user namespace. Because of this, rootless docker containers will run as spc_user_t as docker cannot be SELinux-aware in its own container. Signed-off-by: Kenton Groombridge --- policy/modules/services/container.fc | 8 ++ policy/modules/services/container.if | 59 +++++++++ policy/modules/services/docker.if | 160 +++++++++++++++++++++++++ policy/modules/services/docker.te | 82 +++++++++++++ policy/modules/services/rootlesskit.te | 3 + 5 files changed, 312 insertions(+) diff --git a/policy/modules/services/container.fc b/policy/modules/services/container.fc index 524ccedb1..ef5ad3b69 100644 --- a/policy/modules/services/container.fc +++ b/policy/modules/services/container.fc @@ -9,6 +9,14 @@ HOME_DIR/\.local/share/containers/storage/overlay2-layers(/.*)? gen_context(sys HOME_DIR/\.local/share/containers/storage/overlay-images(/.*)? gen_context(system_u:object_r:container_ro_file_t,s0) HOME_DIR/\.local/share/containers/storage/overlay2-images(/.*)? gen_context(system_u:object_r:container_ro_file_t,s0) HOME_DIR/\.local/share/containers/storage/volumes/[^/]+/.* gen_context(system_u:object_r:container_file_t,s0) +HOME_DIR/\.local/share/docker(/.*)? gen_context(system_u:object_r:container_data_home_t,s0) +HOME_DIR/\.local/share/docker/.*/config\.env -- gen_context(system_u:object_r:container_ro_file_t,s0) +HOME_DIR/\.local/share/docker/containers/.*/.*\.log -- gen_context(system_u:object_r:container_log_t,s0) +HOME_DIR/\.local/share/docker/containers/.*/hostname -- gen_context(system_u:object_r:container_ro_file_t,s0) +HOME_DIR/\.local/share/docker/containers/.*/hosts -- gen_context(system_u:object_r:container_ro_file_t,s0) +HOME_DIR/\.local/share/docker/init(/.*)? gen_context(system_u:object_r:container_ro_file_t,s0) +HOME_DIR/\.local/share/docker/fuse-overlayfs(/.*)? gen_context(system_u:object_r:container_ro_file_t,s0) +HOME_DIR/\.local/share/docker/volumes(/.*)? gen_context(system_u:object_r:container_file_t,s0) /usr/bin/crun -- gen_context(system_u:object_r:container_engine_exec_t,s0) /usr/bin/runc -- gen_context(system_u:object_r:container_engine_exec_t,s0) diff --git a/policy/modules/services/container.if b/policy/modules/services/container.if index 28699f529..e9217f639 100644 --- a/policy/modules/services/container.if +++ b/policy/modules/services/container.if @@ -619,6 +619,28 @@ interface(`container_stream_connect_system_containers',` allow $1 container_runtime_t:sock_file read_sock_file_perms; ') +######################################## +## +## Connect to a user container domain +## over a unix stream socket. +## +## +## +## Domain allowed access. +## +## +# +interface(`container_stream_connect_user_containers',` + gen_require(` + attribute container_user_domain; + type container_runtime_t; + ') + + files_search_runtime($1) + stream_connect_pattern($1, container_runtime_t, container_runtime_t, container_user_domain) + allow $1 container_runtime_t:sock_file read_sock_file_perms; +') + ######################################## ## ## Connect to a container domain @@ -661,6 +683,24 @@ interface(`container_signal_all_containers',` allow $1 container_domain:process signal_perms; ') +######################################## +## +## Set the attributes of container ptys. +## +## +## +## Domain allowed access. +## +## +# +interface(`container_setattr_container_ptys',` + gen_require(` + type container_devpts_t; + ') + + allow $1 container_devpts_t:chr_file setattr; +') + ######################################## ## ## Read and write container ptys. @@ -1156,6 +1196,25 @@ interface(`container_manage_user_runtime_files',` manage_files_pattern($1, container_user_runtime_t, container_user_runtime_t) ') +######################################## +## +## Allow the specified domain to read and +## write user runtime container named sockets. +## +## +## +## Domain allowed access. +## +## +# +interface(`container_rw_user_runtime_sock_files',` + gen_require(` + type container_user_runtime_t; + ') + + allow $1 container_user_runtime_t:sock_file rw_sock_file_perms; +') + ######################################## ## ## Allow the specified domain to search diff --git a/policy/modules/services/docker.if b/policy/modules/services/docker.if index 28965cdb3..6460ed6e0 100644 --- a/policy/modules/services/docker.if +++ b/policy/modules/services/docker.if @@ -46,6 +46,166 @@ interface(`docker_run_cli',` docker_domtrans_cli($1) ') +######################################## +## +## Execute docker in the docker user domain. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`docker_domtrans_user_daemon',` + gen_require(` + type dockerd_user_t, dockerd_exec_t; + ') + + corecmd_search_bin($1) + domtrans_pattern($1, dockerd_exec_t, dockerd_user_t) +') + +######################################## +## +## Execute docker in the docker user +## domain, and allow the specified +## role the docker user domain. +## +## +## +## Domain allowed to transition. +## +## +## +## +## The role to be allowed the docker domain. +## +## +# +interface(`docker_run_user_daemon',` + gen_require(` + type dockerd_user_t; + ') + + role $2 types dockerd_user_t; + + docker_domtrans_user_daemon($1) +') + +######################################## +## +## Execute docker CLI in the docker CLI +## user domain. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`docker_domtrans_user_cli',` + gen_require(` + type dockerc_user_t, dockerc_exec_t; + ') + + corecmd_search_bin($1) + domtrans_pattern($1, dockerc_exec_t, dockerc_user_t) +') + +######################################## +## +## Execute docker CLI in the docker CLI +## user domain, and allow the specified +## role the docker CLI user domain. +## +## +## +## Domain allowed to transition. +## +## +## +## +## The role to be allowed the docker +## user domain. +## +## +# +interface(`docker_run_user_cli',` + gen_require(` + type dockerc_user_t; + ') + + role $2 types dockerc_user_t; + + docker_domtrans_user_cli($1) +') + +######################################## +## +## Role access for rootless docker. +## +## +## +## The prefix of the user role (e.g., user +## is the prefix for user_r). +## +## +## +## +## User domain for the role. +## +## +## +## +## User exec domain for execute and transition access. +## +## +## +## +## Role allowed access. +## +## +## +# +template(`docker_user_role',` + gen_require(` + type dockerd_user_t; + type dockerd_exec_t; + ') + + role $4 types dockerd_user_t; + + docker_run_user_daemon($3, $4) + docker_run_user_cli($3, $4) + + ifdef(`init_systemd',` + systemd_user_daemon_domain($1, dockerd_exec_t, dockerd_user_t) + systemd_user_send_systemd_notify($1, dockerd_user_t) + ') + + optional_policy(` + dbus_spec_session_bus_client($1, dockerd_user_t) + ') +') + +######################################## +## +## Send signals to the rootless docker daemon. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`docker_signal_user_daemon',` + gen_require(` + type dockerd_user_t; + ') + + allow $1 dockerd_user_t:process signal; +') + ######################################## ## ## All of the rules required to diff --git a/policy/modules/services/docker.te b/policy/modules/services/docker.te index 272781270..0e2e2e68e 100644 --- a/policy/modules/services/docker.te +++ b/policy/modules/services/docker.te @@ -20,6 +20,14 @@ type dockerc_exec_t; container_engine_executable_file(dockerc_t) application_domain(dockerc_t, dockerc_exec_t) +container_engine_domain_template(dockerd_user) +container_user_engine(dockerd_user_t) +application_domain(dockerd_user_t, dockerd_exec_t) +mls_trusted_object(dockerd_user_t) + +type dockerc_user_t; +application_domain(dockerc_user_t, dockerc_exec_t) + ######################################## # # Docker daemon local policy @@ -83,3 +91,77 @@ miscfiles_read_localization(dockerc_t) userdom_use_user_ptys(dockerc_t) container_stream_connect_system_containers(dockerc_t) + +######################################## +# +# Rootless Docker daemon local policy +# + +# rootless docker is really just docker running as root, but in a user namespace + +allow dockerd_user_t self:netlink_netfilter_socket create_socket_perms; +allow dockerd_user_t self:netlink_xfrm_socket create_socket_perms; + +fs_getattr_fusefs(dockerd_user_t) +fs_mount_fusefs(dockerd_user_t) +fs_unmount_fusefs(dockerd_user_t) +fs_remount_fusefs(dockerd_user_t) +fs_manage_fusefs_dirs(dockerd_user_t) +fs_manage_fusefs_files(dockerd_user_t) +fs_manage_fusefs_symlinks(dockerd_user_t) +fs_exec_fusefs_files(dockerd_user_t) +fs_mounton_fusefs(dockerd_user_t) + +kernel_dontaudit_request_load_module(dockerd_user_t) + +storage_rw_fuse(dockerd_user_t) + +init_write_runtime_socket(dockerd_user_t) + +logging_send_syslog_msg(dockerd_user_t) + +mount_exec(dockerd_user_t) + +container_setattr_container_ptys(dockerd_user_t) +container_use_container_ptys(dockerd_user_t) + +rootlesskit_exec(dockerd_user_t) + +ifdef(`init_systemd',` + systemd_search_user_runtime(dockerd_user_t) + systemd_write_user_runtime_socket(dockerd_user_t) + systemd_start_user_runtime_units(dockerd_user_t) + systemd_stop_user_runtime_units(dockerd_user_t) + systemd_status_user_runtime_units(dockerd_user_t) +') + +optional_policy(` + dbus_getattr_session_runtime_socket(dockerd_user_t) + dbus_write_session_runtime_socket(dockerd_user_t) +') + +######################################## +# +# Rootless Docker CLI local policy +# + +allow dockerc_user_t self:process { getsched signal }; +allow dockerc_user_t self:fifo_file rw_fifo_file_perms; + +allow dockerc_user_t dockerd_user_t:unix_stream_socket connectto; + +corecmd_search_bin(dockerc_user_t) + +domain_use_interactive_fds(dockerc_user_t) + +auth_use_nsswitch(dockerc_user_t) + +miscfiles_read_localization(dockerc_user_t) + +userdom_use_user_ptys(dockerc_user_t) +userdom_search_user_home_dirs(dockerc_user_t) +userdom_search_user_runtime(dockerc_user_t) + +xdg_search_data_dirs(dockerc_user_t) + +container_stream_connect_user_containers(dockerc_user_t) diff --git a/policy/modules/services/rootlesskit.te b/policy/modules/services/rootlesskit.te index 31168801d..208143c6f 100644 --- a/policy/modules/services/rootlesskit.te +++ b/policy/modules/services/rootlesskit.te @@ -37,6 +37,9 @@ auth_use_nsswitch(rootlesskit_t) userdom_exec_user_bin_files(rootlesskit_t) +docker_domtrans_user_daemon(rootlesskit_t) +docker_signal_user_daemon(rootlesskit_t) + optional_policy(` dbus_list_system_bus_runtime(rootlesskit_t) dbus_system_bus_client(rootlesskit_t)