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

Recent Docker folder permissions change to 0701 - Unprivileged users can read/write/exec container's files #42411

Open
joanbm opened this issue May 24, 2021 · 2 comments

Comments

@joanbm
Copy link

joanbm commented May 24, 2021

Description

I noticed that in recent Docker versions (e.g. 20.10.6), when running a "classic" out-of-the-box Docker setup (i.e. with default settings, in overlay2 mode, without rootless or userns-remap mode, etc.), an unprivileged user (i.e. new user account with no sudo rights, not in the docker group, etc.) can navigate and read the contents of a running container's root filesystem, i.e. of the "/var/lib/docker/overlay2/[some hex id]/merged" directories. Here "[some hex id]" is a code generated by Docker, and can be obtained by simply listing the mounts with the "mount" command while the container is running.

As an illustration, here's how one can navigate to the contents of a container's root file system as an unprivileged user:

  • Install a very recent version of Docker, e.g 20.10.6, for example in an Ubuntu 20.04 host using the official Docker PPA (https://docs.docker.com/engine/install/ubuntu/).
  • As some user who can run containers, launch any container, e.g.: docker run --rm -d alpine:3.13 sleep 999999
  • As an unprivileged user with no permissions related to Docker, run: ls $(mount | grep merged | cut -f3 -d" ")
  • You will see an output like bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var, i.e. the listing of files in the container root filesystem.

As mentioned, this only works in recent Docker versions such as 20.10.6, and in fact, this seems to be the expected behaviour since commit 7f5e39b, which changes permissions from 0700 to 0701 for the folders on /var/lib/docker and thus allows any user to traverse those paths.

Additionally to browsing the container's files, those are also possible:

  • An unprivileged user can modify some running container's files, as long as its UID matches that of an user within the container.
  • An unprivileged user can run a malicious SUID binary, or exploit a vulnerable SUID binary, which is contained within a running container (or even a pulled image), even if the container never uses this SUID binary in a way that could trigger the issue.

I know there are more secure ways to run Docker than the out-of-the-box configuration, and I acknowledge that I'm not the most familiar person with Docker's security model, so maybe this issue is bogus or it's well-known that an unprivileged user can do this, but it is surprising regardless.

Steps to reproduce the issue:

As a proof of concept for this last case, I built a simple Ubuntu 20.04 container where I gave SUID permissions to "cat", and uploaded it to joanbm/test-suid, using this Dockerfile:

FROM ubuntu:20.04
RUN chmod u+s /usr/bin/cat

On an Ubuntu 20.04 host, as some user who can run containers, launch this container with a simple sleep command:
docker run --rm -d joanbm/test-suid sleep 9999999
Than, as an unprivileged user with no permissions related to Docker, run:
$(mount | grep merged | cut -f3 -d" ")/usr/bin/cat /etc/shadow
And it will print the content of /etc/shadow on the host, from the command run by the unprivileged user, which I believe should not normally happen. Note this could also easily be used to launch a root shell by giving SUID to the shell instead of cat.

Describe the results you received:

An unprivileged user with no extra permissions related to Docker can access, a running container's files, potentially modify them, and run SUID binaries.

Describe the results you expected:

The unprivileged user should have no access to the container's files.

Output of docker version:

Client: Docker Engine - Community
 Version:           20.10.6
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        370c289
 Built:             Fri Apr  9 22:47:17 2021
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.6
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       8728dd2
  Built:            Fri Apr  9 22:45:28 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.4
  GitCommit:        05f951a3781f4f2c1911b05e61c160e9c30eaa8e
 runc:
  Version:          1.0.0-rc93
  GitCommit:        12644e614e25b05da6fd08a38ffa0cfe1903fdec
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Output of docker info:

Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)
  scan: Docker Scan (Docker Inc., v0.7.0)

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 20.10.6
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 05f951a3781f4f2c1911b05e61c160e9c30eaa8e
 runc version: 12644e614e25b05da6fd08a38ffa0cfe1903fdec
 init version: de40ad0
 Security Options:
  apparmor
  seccomp
   Profile: default
 Kernel Version: 5.4.0-73-generic
 Operating System: Ubuntu 20.04.2 LTS
 OSType: linux
 Architecture: x86_64
 CPUs: 1
 Total Memory: 981.3MiB
 Name: ubuntu-s-1vcpu-1gb-fra1-01
 ID: XLDO:FBNC:4R3Y:V37P:SQQM:J7QU:BA3H:XEXG:2AC4:R6DS:5QFA:55YC
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

WARNING: No swap limit support

Additional environment details (AWS, VirtualBox, physical, etc.):

DigitalOcean $5 Ubuntu 20.04 droplet. (It also reproduces on my bare metal Arch Linux install.)

@joanbm joanbm changed the title Recent Docker folder permissions change to 0701 - Unprivileged users access to container's files Recent Docker folder permissions change to 0701 - Unprivileged users can read/write/exec container's files May 24, 2021
@joanbm
Copy link
Author

joanbm commented May 30, 2021

BTW, if I understand the commit correctly, the idea is to give the remapped root user (in userns-remap mode) the right to traverse the folders under /var/lib/docker. If this is the case, shouldn't an ACL giving the traversal (x bit) only to the remapped root user suffice?

That's the approach I've seen for LXC e.g. https://wiki.debian.org/LXC (ctrl+f "setfacl").

CC @cpuguy83 ?

@cpuguy83
Copy link
Member

@joanbm Just wanted to say we aren't ignoring the issue.

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

No branches or pull requests

2 participants