The ultimate goal of almost every hacker is to go up. To step up. To grab root, and use it to go higher or lower on the stack, depending upon your perspective. That first foothold is the key element in any outright cyber-attack: the one piton from which the unwanted climbers make their first ascent.
The job of the administrator is to be the Yeti, the wind, the earthquake and rock slide to repel the would-be summiters from their assault. In digital terms, this means securing the end points, keeping data safe in transit and staying up to date with the latest vulnerabilities.
Unfortunately, there are some problems we encounter in software that cannot be mitigated without great forethought. In fact, you need the patience of a rock of ages; in software, five years is a long time.
Before we get into our Q&A on CVE-2021-30465 with Red Hat’s security wizards, Mrunal Patel and Dan Walsh (Feel free to skip ahead to that section if you already know the story of SELinux), we first want to be absolutely clear that the Red Hat OpenShift in all of its various forms significantly reduces the danger of CVE-2021-20465 through the layered security offered by SELinux which is enabled by default in OpenShift, and has protected against this and previous variants of this type of exploit.
At its core, this exploit stems from the ability of a cluster user running a container to gain write access to the underlying worker node’s file system. This is the common nightmare scenario, where something at the top of the stack can reach down and compromise the multi-tenant machine below it, or here, the Kubernetes cluster.
To be clear, all Kubernetes clusters are vulnerable, at present, to this vulnerability in Runc, which is a core component of all OCI compliant container runtimes. It’s the default implementation of the OCI runtime specification. CRI-O calls runc, and so do containerd and other OCI container runtimes.
Because OpenShift takes advantage of SELinux and combines it with OpenShift Security Context Constraints (SCC) that define and enforce policies for what pod users can deploy to OpenShift Kubernetes clusters, newly deployed containers are constrained in their access rights, by default. This has been the case for 5 years now, and is actually a feature of the platform, built in at the base.
This is why, sometimes, you’ll encounter a container image that will run on any other Kubernetes, but will not run on OpenShift. The secure by default SCC policies that OpenShift uses have prevented a violation, whether that’s a container someone is trying to run, a privileged container, or a container that is not enabled to run with SELinux enforcing or something else SCC policies can govern. OpenShift Administrators can relax their SCC policies to be more permissive and allow users to deploy pods/containers with fewer restrictions by default, but these are decisions that should be taken with caution - as the runc CVE illustrates.
Because this benefit derives from these layered security features of the OpenShift platform working as an integrated unit, the rest of the Kubernetes community does not benefit from this added layer of security. It’s entirely possible to put this type of capability together in any Kubernetes using the entirely open source components we’ve used here, as well. It’s simply that Red Hat does all that hard work so you don’t have to.
We’ve also worked to drive similar capabilities in upstream Kubernetes, initially via "Pod Security Policies" ( which has since been deprecated) and more recently in an alternative approach to PSPs which we hope will be upstream in alpha form soon.
Q&A With Mrunal Patel and Dan Walsh on CVE-2021-30465 and OpenShift
Can you give us a quick overview of this runc vulnerability?
Basically, through an attack vector using symbolic links via Kubernetes, a user was able to leak “/” of the host into the container. The result derives from the fact that the user can create a pod and launch this attack, which allows a “container filesystem breakout via directory traversal,” as described in the CVE.
Does this impact all Linux containers and Kubernetes users, and how exposed are they?
Yes, the proof-of-concept reproducer has a pod definition and steps that can be run by a user to make the host filesystem available inside the containers in the pod. Notably, even pods running under the restricted SCC would be able to reproduce the issue.
How does this compare to other vulnerabilities you've seen in the past at the container runtime layer?
We have had far worse. But this is pretty bad because, as with most escapes, the processes inside of the container gets access to the host file system.
Can you give us the basics on SELinux and how it helps mitigate this type of vulnerability?
SELinux is a labeling system. Each process gets a label and all of the file/directories on the system get a label. We write rules allowing for which files a label is able to read/write. By default container labeled processes are only allowed to write to container files, so if a container escapes to the host file system, it can not write to anywhere but the content of the container. Containers are allowed to read labels in /usr, and the default label in /etc. They are pretty much prevented from reading all other labels, Including everything in /var, /home, /root or any random directories added to the host. They are also prevented from reading/writing content in other containers. This is true whether or not a container is running as root. Container processes are also blocked from communicating with other processes on the system via IPC and Unix domain sockets. This means a container process would not be allowed to communicate or influence systemd, as an example.
How are OpenShift Kubernetes users protected (given that SELinux is enabled by default)?
They get all of the protection described above. Also since containers in OpenShift default to running as non-root, via the OpenShift SCC policy capabilities described previously, they would be blocked from reading/writing content that is not available to non-root users. By default SELinux is always enabled in OpenShift. SCC and our OpenShift default policies enforce that you are limited to run in an SELinux content and run as non-root. SELinux enforces stuff at the kernel level (i.e. container host). This would apply to any container image you bring to OpenShift and try to deploy in a pod to an OpenShift Kubernetes cluster.