In a recent post by ZDI, researchers found an out-of-bounds access flaw (CVE-2021-31440) in the Linux kernel’s (5.11.15) implementation of the eBPF code verifier: an incorrect register bounds calculation occurs while checking unsigned 32-bit instructions in an eBPF program. The flaw can be leveraged to escalate privileges and execute arbitrary code in the context of the kernel.
This vulnerability allows a local privilege escalation, which means an attacker with non-root access to the system can gain higher privileges by exploiting this vulnerability. The non-root access can be a user account without sudo or group privileges, which are usually provided to the application user.
Why you should be worried
In a Kubernetes environment, containers use the host kernel to run themselves. Therefore, the execution of malicious eBPF code as an unprivileged user in the context of the kernel can result in container escape and privilege escalation to the host.
Unprivileged users inside the container need CAP_SYS_ADMIN permission already assigned to the container to run a malicious eBPF program. For Linux kernels 5.8 and above, a new permission, CAP_BPF, is added to allow users to run eBPF programs. CAP_BPF is a subset of CAP_SYS_ADMIN.
In Kubernetes, privileged containers inherit CAP_SYS_ADMIN privileges by default. As a result, unprivileged users inside a privileged container can escalate privileges to the node and break out of the container at the same time, using this vulnerability.
Additionally, the exploit code is generally available on the internet. We expect various malwares targeting Kubernetes will be adding this exploit to escalate privileges after compromise.
Fixes have been released for Linux kernel versions 5.10.37, 5.11.21, and 5.12.4. It is best practice to upgrade your kernel version when fixes are available for your upstream Linux distribution. In the meantime, you can use the following mitigation approach.
1. Disable unprivileged eBPF execution on nodes
To mitigate this vulnerability, you need to prevent unprivileged users from being able to run eBPF to inject untrusted code. This can be achieved with the following command, which disables unprivileged eBPF execution on Kubernetes nodes.
$ sudo sysctl kernel.unprivileged_bpf_disabled=1
You can confirm changes using the following command, which should have value ‘1’.
$ cat /proc/sys/kernel/unprivileged_bpf_disabled 1
2. Don’t grant CAP_SYS_ADMIN privileges to containers
As we have seen, privileged containers have CAP_SYS_ADMIN privileges by default. If unprivileged eBPF execution is not disabled on the Kubernetes node, unprivileged users from privileged containers can run malicious code to escalate their privileges.
3. Don’t grant CAP_BPF permission to containers running on Linux kernel 5.8 and above
If you are using Linux kernel 5.8 and above, you can look for CAP_BPF permission granted to the container in addition to CAP_SYS_ADMIN to remediate this issue on the container front.
4. Run application as non-root user
Run your application within a privileged container as non-root. If the above discussed mitigations are in place, this will ensure that, after a compromise, unprivileged users won’t be able to escalate privileges using this vulnerability. The impact would be limited to the application or service that has been compromised.
5. Use zero trust
A zero-trust policy can help limit an attacker’s lateral movement within the Kubernetes cluster if the attacker is not able to escalate privileges after initial compromise due to the above-mentioned mitigations.
How Calico addresses this vulnerability
Calico users using eBPF for higher performance in their Kubernetes clusters are protected from this vulnerability. Calico voluntarily disables unprivileged execution of eBPF code so that regardless of the Linux distribution being used, all customers running eBPF in their Kubernetes clusters are protected.
Did you know you can become a certified Calico operator? Learn Kubernetes networking and security fundamentals using Calico in this free, self-paced certification course.