Skip to content

Commit

Permalink
selinux-policy: add file read restrictions
Browse files Browse the repository at this point in the history
Since host container user data can be used to pass secrets, we should
block reads as well as writes to this content. Similarly, because the
user data is saved in the datastore, we should also restrict access
to those files.

Signed-off-by: Ben Cressey <[email protected]>
  • Loading branch information
bcressey committed Apr 7, 2021
1 parent eace86a commit ea35f1b
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 30 deletions.
2 changes: 1 addition & 1 deletion packages/os/host-containers-tmpfiles.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
d /etc/host-containers 0755 root root -
d /local/host-containers 0700 root root -
T /local/host-containers - - - - security.selinux=system_u:object_r:state_t:s0
T /local/host-containers - - - - security.selinux=system_u:object_r:secret_t:s0
55 changes: 45 additions & 10 deletions packages/selinux-policy/files.cil
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Permission groups for files.
(classmap files (relabel mount relax enter load mutate block))
(classmap files (relabel mount relax enter describe load mutate block))

; Permission group for relabeling files.
(classmapping files relabel relabel_file)
Expand Down Expand Up @@ -34,6 +34,16 @@
; Permission group for using files as entry points.
(classmapping files enter enter_file)

; Permission group for describing files.
(classmapping files describe describe_file)
(classmapping files describe describe_dir)
(classmapping files describe describe_lnk_file)
(classmapping files describe describe_chr_file)
(classmapping files describe describe_blk_file)
(classmapping files describe describe_sock_file)
(classmapping files describe describe_fifo_file)
(classmapping files describe describe_filesystem)

; Permission group for reading and executing files.
(classmapping files load load_file)
(classmapping files load load_dir)
Expand Down Expand Up @@ -146,6 +156,32 @@
(classpermissionset enter_file (
file (entrypoint)))

; Sets of permissions for describing file objects.
(classpermission describe_file)
(classpermission describe_dir)
(classpermission describe_lnk_file)
(classpermission describe_chr_file)
(classpermission describe_blk_file)
(classpermission describe_sock_file)
(classpermission describe_fifo_file)
(classpermission describe_filesystem)
(classpermissionset describe_file (
file (getattr)))
(classpermissionset describe_dir (
dir (getattr)))
(classpermissionset describe_lnk_file (
lnk_file (getattr)))
(classpermissionset describe_chr_file (
chr_file (getattr)))
(classpermissionset describe_blk_file (
blk_file (getattr)))
(classpermissionset describe_sock_file (
sock_file (getattr)))
(classpermissionset describe_fifo_file (
fifo_file (getattr)))
(classpermissionset describe_filesystem (
filesystem (getattr quotaget)))

; Sets of permissions for read-only actions that do not affect the
; integrity of file objects.
(classpermission load_file)
Expand All @@ -159,35 +195,34 @@
(classpermission load_fd)
(classpermissionset load_file (
file (
execute getattr ioctl map open read execute_no_trans
execute ioctl map open read execute_no_trans
watch watch_mount watch_reads watch_sb)))
(classpermissionset load_dir (
dir (
execute getattr ioctl map open read search
execute ioctl map open read search
watch watch_mount watch_reads watch_sb)))
(classpermissionset load_lnk_file (
lnk_file (
execute ioctl getattr map open read
execute ioctl map open read
watch watch_mount watch_reads watch_sb)))
(classpermissionset load_chr_file (
chr_file (
execute ioctl getattr map open read
execute ioctl map open read
watch watch_mount watch_reads watch_sb)))
(classpermissionset load_blk_file (
blk_file (
execute ioctl getattr map open read
execute ioctl map open read
watch watch_mount watch_reads watch_sb)))
(classpermissionset load_sock_file (
sock_file (
execute ioctl getattr map open read
execute ioctl map open read
watch watch_mount watch_reads watch_sb)))
(classpermissionset load_fifo_file (
fifo_file (
execute ioctl getattr map open read
execute ioctl map open read
watch watch_mount watch_reads watch_sb)))
(classpermissionset load_filesystem (
filesystem (
getattr quotaget watch)))
filesystem (watch)))
(classpermissionset load_fd (
fd (use)))

Expand Down
4 changes: 2 additions & 2 deletions packages/selinux-policy/fs.cil
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@
(filecon "/var/.*" any ())

; Label local state directories.
(filecon "/local/host-containers" any state)
(filecon "/local/host-containers/.*" any state)
(filecon "/local/host-containers" any secret)
(filecon "/local/host-containers/.*" any secret)
(filecon "/var/lib/chrony" any measure)
(filecon "/var/lib/chrony/.*" any measure)
(filecon "/var/lib/systemd" any state)
Expand Down
13 changes: 11 additions & 2 deletions packages/selinux-policy/object.cil
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@
(roletype object_r state_t)
(context state (system_u object_r state_t s0))

; Files for saved system secrets.
(type secret_t)
(roletype object_r secret_t)
(context secret (system_u object_r secret_t s0))

; Files that are mount points for external filesystems.
(type external_t)
(roletype object_r external_t)
Expand All @@ -112,7 +117,11 @@
; Protected objects are files on local storage with special rules.
(typeattribute protected_o)
(typeattributeset protected_o (
cache_t private_t lease_t measure_t state_t))
cache_t private_t lease_t measure_t secret_t state_t))

; Restricted objects are files that cannot be read by all processes.
(typeattribute restricted_o)
(typeattributeset restricted_o (private_t secret_t))

; Immutable objects reside on read-only storage.
(typeattribute immutable_o)
Expand All @@ -132,6 +141,6 @@
os_t init_exec_t api_exec_t clock_exec_t
network_exec_t bus_exec_t runtime_exec_t
any_t etc_t unlabeled_t external_t
local_t private_t cache_t
local_t private_t secret_t cache_t
lease_t measure_t state_t
api_socket_t))
47 changes: 33 additions & 14 deletions packages/selinux-policy/rules.cil
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
; Deny any action that is not defined by the policy.
(handleunknown deny)

; Define the set of all subject and object types, to allow certain
; actions to be whitelisted or blacklisted for everything.
; Define the set of all subject and object types, to allow certain actions to
; be allowed or denied for everything.
(typeattribute global)
(typeattributeset global ((all_s) (all_o)))

; Define a subset of these types which are considered public.
(typeattribute public)
(typeattributeset public (xor (global) (restricted_o)))

; All subjects are allowed to use the label they already have.
(allow all_s self (processes (transform)))

; All subjects are allowed to read and execute all files.
(allow all_s global (files (load)))

; All subjects are allowed to interact with processes in
; most ways without policy restrictions.
(allow all_s global (processes (interact)))
Expand Down Expand Up @@ -62,11 +63,11 @@
; unprivileged containers, unless automatic labeling is disabled.
(typetransition runtime_t local_t process control_t)
(typetransition runtime_t cache_t process control_t)
(typetransition runtime_t state_t process control_t)
(typetransition runtime_t secret_t process control_t)
(allow runtime_t container_s (processes (transform)))
(allow container_s local_t (file (entrypoint)))
(allow container_s cache_t (file (entrypoint)))
(allow container_s state_t (file (entrypoint)))
(allow container_s secret_t (file (entrypoint)))

; Also allow entry to container domains through `docker-init`, which
; is mounted from the root filesystem and used as the init process.
Expand All @@ -92,12 +93,24 @@
(typetransition runtime_t local_t dir "overlay2" cache_t)

; If a system process creates a directory for host container state, it
; receives the "state_t" label.
(typetransition system_t local_t dir "host-containers" state_t)
; receives the "secret_t" label.
(typetransition system_t local_t dir "host-containers" secret_t)

; The socket for the API server gets the "api_socket_t" label.
(typetransition api_t any_t sock_file "api.sock" api_socket_t)

; All subjects can describe anything.
(allow all_s global (files (describe)))

; All subjects can read from anything that's public.
(allow all_s public (files (load)))

; Trusted subjects can read from anything at all.
(allow trusted_s global (files (load)))

; Untrusted subjects cannot read from restricted objects.
(neverallow untrusted_s restricted_o (files (load)))

; All subjects are allowed to write to objects with their own label.
; This includes files like the ones under /proc/self.
(allow all_s self (files (mutate)))
Expand All @@ -121,19 +134,25 @@
(allow unconfined_s local_t (files (mutate mount)))

; Subjects that control the OS, including helpers spawned by apiserver, can
; write to and manage mounts for "state" files and directories on /local.
; write to and manage mounts for "secret" files and directories on /local.
; Our runtimes also need to be able to perform these operations so that
; they can launch host containers.
(allow api_s state_t (files (mutate mount)))
(allow api_s secret_t (files (mutate mount)))
(allow control_s secret_t (files (mutate mount)))
(allow runtime_s secret_t (files (mutate mount)))

; Subjects that control the OS can write to and manage mounts for "state"
; files and directories on /local.
(allow control_s state_t (files (mutate mount)))
(allow runtime_s state_t (files (mutate mount)))

; Untrusted subjects cannot modify the "state" files.
; Untrusted subjects cannot modify "state" or "secret" files.
(neverallow untrusted_s state_t (files (mutate mount)))
(neverallow untrusted_s secret_t (files (mutate mount)))

; Confined subjects cannot modify either "state" or "local" files.
; Confined subjects cannot modify "state", "secret", or "local" files.
(neverallow confined_s local_t (files (mutate mount)))
(neverallow confined_s state_t (files (mutate mount)))
(neverallow confined_s secret_t (files (mutate mount)))

; Trusted components are allowed to manage mounts everywhere.
(allow trusted_s global (files (mount)))
Expand Down
2 changes: 1 addition & 1 deletion sources/host-ctr/cmd/host-ctr/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ func runCtr(containerdSocket string, namespace string, containerID string, sourc
// Mount in the persistent storage location for this container
withPersistentStorage(containerID),
// Mount the rootfs with an SELinux label that makes it writable
withMountLabel("system_u:object_r:state_t:s0"),
withMountLabel("system_u:object_r:secret_t:s0"),
// Include conditional options for superpowered containers.
withSuperpowered(superpowered),
)
Expand Down

0 comments on commit ea35f1b

Please sign in to comment.