Unable to use unshare during build process even though whitelisted in seccomp profile
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 10.3k
- Forks
- 1.5k
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 48
Description
I am running docker with a modified seccomp profile that whitelists unshare, mount, umount, and umount2. If I try to build an image with buildkit with a Dockerfile that uses unshare in a RUN line, the image fails to build. If DOCKER_BUILDKIT is unset, then it builds successfully.
laptop [~/foo]$ cat Dockerfile
FROM debian:jessie
RUN unshare --user --map-root-user whoami
laptop [~/foo]$ unset DOCKER_BUILDKIT
laptop [~/foo]$ docker build -t foo .
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM debian:jessie
---> bb64860610f6
Step 2/2 : RUN unshare --user --map-root-user whoami
---> Running in 0d4c19785d68
root
Removing intermediate container 0d4c19785d68
---> 8f68c667c8d8
Successfully built 8f68c667c8d8
Successfully tagged foo:latest
laptop [~/foo]$ export DOCKER_BUILDKIT=1
laptop [~/foo]$ docker build -t foo .
[+] Building 0.7s (5/5) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.2s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/debian:jessie 0.0s
=> CACHED [1/2] FROM docker.io/library/debian:jessie 0.0s
=> ERROR [2/2] RUN unshare --user --map-root-user whoami 0.5s
------
> [2/2] RUN unshare --user --map-root-user whoami:
#5 0.352 unshare: unshare failed: Operation not permitted
------
executor failed running [/bin/sh -c unshare --user --map-root-user whoami]: exit code: 1
laptop [~/foo]$ uname -r
4.20.1-arch1-1-ARCH
laptop [~/foo]$ docker version
Client:
Version: 18.09.1-ce
API version: 1.39
Go version: go1.11.4
Git commit: 4c52b901c6
Built: Thu Jan 10 06:51:04 2019
OS/Arch: linux/amd64
Experimental: false
Server:
Engine:
Version: 18.09.1-ce
API version: 1.39 (minimum version 1.12)
Go version: go1.11.4
Git commit: 4c52b901c6
Built: Thu Jan 10 06:50:46 2019
OS/Arch: linux/amd64
Experimental: false
laptop [~/foo]$ docker info
Containers: 6
Running: 1
Paused: 0
Stopped: 5
Images: 264
Server Version: 18.09.1-ce
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 9f2e07b1fc1342d1c48fe4d7bbb94cb6d1bf278b.m
runc version: 079817cc26ec5292ac375bb9f47f373d33574949
init version: fec3683
Security Options:
seccomp
WARNING: You're not using the default seccomp profile
Profile: /etc/docker/seccomp.json
Kernel Version: 4.20.1-arch1-1-ARCH
Operating System: Arch Linux
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 15.42GiB
Name: laptop
ID: EWRT:BUVO:GBFG:4O5M:IQN7:332P:ZDRZ:AWSC:OZUN:2YQ2:U2D4:Q7FT
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Username: tbeadle
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
[root@laptop docker]# sysctl -a | grep userns
kernel.unprivileged_userns_clone = 1
[root@laptop docker]# sysctl -a | grep namespace
user.max_cgroup_namespaces = 62874
user.max_ipc_namespaces = 62874
user.max_mnt_namespaces = 62874
user.max_net_namespaces = 62874
user.max_pid_namespaces = 62874
user.max_user_namespaces = 62874
user.max_uts_namespaces = 62874
[root@laptop docker]# ps -efww | grep docker
root 16077 1 0 17:41 ? 00:01:53 /usr/bin/dockerd -H fd:// --seccomp-profile=/etc/docker/seccomp.json
root 16085 16077 0 17:41 ? 00:00:08 containerd --config /var/run/docker/containerd/containerd.toml --log-level info
The seccomp profile that I using is the same as the default one (from https://raw.githubusercontent.com/moby/moby/master/profiles/seccomp/default.json) except with the following changes to whitelist unshare, mount, umount, and umount2:
laptop [~/foo]$ diff ~/default.json /etc/docker/seccomp.json
196a197
> "mount",
348a350,351
> "umount",
> "umount2",
351a355
> "unshare",
556d559
< "mount",
563,566c566
< "syslog",
< "umount",
< "umount2",
< "unshare"
---
> "syslog"
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Dockerfile reproducer and compare the legacy docker build with DOCKER_BUILDKIT=1. Inspect /etc/docker/seccomp.json alongside the referenced default profile, then trace the BuildKit execution path; done means the unshare command succeeds under BuildKit with the stated syscall whitelist.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, go, linux
- Domain
- build-system, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100