Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

split SELinux policy rules for trusted subjects #1558

Merged
merged 1 commit into from
May 5, 2021

Conversation

bcressey
Copy link
Contributor

@bcressey bcressey commented May 4, 2021

Issue number:
N/A

Description of changes:

Since 59264b48, privileged containers have received the `control_t`
label by default. This label is treated as a trusted subject, and has
broad powers of system configuration, including the ability to modify
files in /etc or change SELinux labels.

However, because these powers are granted by default, it creates the
risk of accidental misconfiguration, where files in /etc are modified
without realizing that these changes will be lost on reboot. Changing
SELinux labels can also happen unexpectedly, and could interfere with
the operation of the host or the reliability of upgrades.

To fix this, we split the rules for trusted subjects in two, to match
the expected access boundaries between privileged containers and the
underlying host.

Privileged subjects can still interact with all processes and read
all files, but can no longer change SELinux labels or edit files in
/etc. They also cannot unmount system mounts, or interact directly
with systemd or dbus.

Testing done:
dev, ecs, and k8s variants booted up and ran containers without AVC denials.

Ran a privileged pod:

❯ kubectl exec -ti privileged-pod -- bash

bash-4.2# cat /proc/self/attr/current
system_u:system_r:control_t:s0

bash-4.2# apiclient set motd="hello"

bash-4.2# touch /host-root/etc/foo
touch: cannot touch '/host-root/etc/foo': Permission denied
[  309.381083] audit: type=1400 audit(1620158963.124:5): avc:  denied  { write } for  pid=15157 comm="touch" name="/" dev="tmpfs" ino=9325 scontext=system_u:system_r:control_t:s0 tcontext=system_u:object_r:etc_t:s0 tclass=dir permissive=0

bash-4.2# ls -latrZ /host-root/local/host-containers
drwxr-xr-x. root root system_u:object_r:local_t:s0     ..
drwx------. root root system_u:object_r:secret_t:s0    .
drwx------. root root system_u:object_r:secret_t:s0    control
drwx------. root root system_u:object_r:secret_t:s0    admin

bash-4.2# setfattr -n security.selinux -v system_u:object_r:any_t:s0 /host-root/tmp/.font-unix/
setfattr: /host-root/tmp/.font-unix/: Permission denied
[ 2455.787311] audit: type=1400 audit(1620161109.479:13): avc:  denied  { relabelfrom } for  pid=46913 comm="setfattr" name=".font-unix" dev="tmpfs" ino=12510 scontext=system_u:system_r:control_t:s0 tcontext=system_u:object_r:any_t:s0 tclass=dir permissive=0

Ran an unprivileged pod. It couldn't write to the API socket, modify files in /etc, read restricted directories, or relabel files.

❯ kubectl exec -ti unprivileged-pod -- bash

bash-4.2# cat /proc/self/attr/current
system_u:system_r:container_t:s0:c332,c393

bash-4.2# apiclient set motd="hello"
Failed to change settings: Failed PATCH request to '/settings?tx=apiclient-set-yc2lgVzll4pxV4gM': Failed to send request: error trying to connect: Permission denied (os error 13)
[ 1120.216432] audit: type=1400 audit(1620159773.942:8): avc:  denied  { write } for  pid=27440 comm="apiclient" name="api.sock" dev="tmpfs" ino=13828 scontext=system_u:system_r:container_t:s0:c332,c393 tcontext=system_u:object_r:api_socket_t:s0 tclass=sock_file permissive=0

bash-4.2# touch /host-root/etc/foo
touch: cannot touch '/host-root/etc/foo': Permission denied
[ 1144.664059] audit: type=1400 audit(1620159798.389:9): avc:  denied  { write } for  pid=27804 comm="touch" name="/" dev="tmpfs" ino=9325 scontext=system_u:system_r:container_t:s0:c332,c393 tcontext=system_u:object_r:etc_t:s0 tclass=dir permissive=0

bash-4.2# ls -latrZ /host-root/local/host-containers
setfattr: /host-root/local/host-containers: Permission denied
[ 2278.910547] audit: type=1400 audit(1620160932.607:12): avc:  denied  { read } for  pid=44369 comm="ls" name="host-containers" dev="nvme1n1p1" ino=1046529 scontext=system_u:system_r:container_t:s0:c332,c393 tcontext=system_u:object_r:secret_t:s0 tclass=dir permissive=0

bash-4.2# setfattr -n security.selinux -v system_u:object_r:any_t:s0 /host-root/tmp/.font-unix/
[ 2225.201995] audit: type=1400 audit(1620160878.901:11): avc:  denied  { relabelfrom } for  pid=43535 comm="setfattr" name=".font-unix" dev="tmpfs" ino=12510 scontext=system_u:system_r:container_t:s0:c332,c393 tcontext=system_u:object_r:any_t:s0 tclass=dir permissive=0

Ran a superpowered pod, which could do all of the above:

❯ kubectl exec -ti admin-pod -- bash

bash-4.2# cat /proc/self/attr/current
system_u:system_r:super_t:s0

bash-4.2# apiclient set motd="hello"

bash-4.2# touch /host-root/etc/foo

bash-4.2# ls -latrZ /host-root/local/host-containers
drwxr-xr-x. root root system_u:object_r:local_t:s0     ..
drwx------. root root system_u:object_r:secret_t:s0    .
drwx------. root root system_u:object_r:secret_t:s0    control
drwx------. root root system_u:object_r:secret_t:s0    admin

bash-4.2# setfattr -n security.selinux -v system_u:object_r:any_t:s0 /host-root/tmp/.font-unix/

Terms of contribution:

By submitting this pull request, I agree that this contribution is dual-licensed under the terms of both the Apache License, version 2.0, and the MIT license.

Since 59264b4, privileged containers have received the `control_t`
label by default. This label is treated as a trusted subject, and has
broad powers of system configuration, including the ability to modify
files in /etc or change SELinux labels.

However, because these powers are granted by default, it creates the
risk of accidental misconfiguration, where files in /etc are modified
without realizing that these changes will be lost on reboot. Changing
SELinux labels can also happen unexpectedly, and could interfere with
the operation of the host or the reliability of upgrades.

To fix this, we split the rules for trusted subjects in two, to match
the expected access boundaries between privileged containers and the
underlying host.

Privileged subjects can still interact with all processes and read
all files, but can no longer change SELinux labels or edit files in
/etc. They also cannot unmount system mounts, or interact directly
with systemd or dbus.

Signed-off-by: Ben Cressey <bcressey@amazon.com>
@bcressey bcressey requested a review from tjkirch May 4, 2021 21:04
packages/selinux-policy/rules.cil Show resolved Hide resolved
packages/selinux-policy/subject.cil Show resolved Hide resolved
Copy link
Contributor

@arnaldo2792 arnaldo2792 left a comment

Choose a reason for hiding this comment

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

👢

@bcressey bcressey merged commit f93f9fe into bottlerocket-os:develop May 5, 2021
@bcressey bcressey deleted the split-trusted-rules branch May 5, 2021 00:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants