moby: ptrace(ltrace/strace) does not work on non-privileged mode even apparmor is disabled and SYS_PTRACE is enabled.

Adding both “–cap-add=SYS_PTRACE” and “–security-opt=apparmor:unconfined” does not allow container to run programs like strace/ltrace using the ptrace (PTRACE_TRACEME).

$ docker run -i -t --cap-add=SYS_PTRACE --security-opt=apparmor:unconfined --rm ubuntu sh -c 'apt-get install -y strace; strace /bin/ls'
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  strace
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 113 kB of archives.
After this operation, 504 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu/ trusty/main strace amd64 4.8-1ubuntu5 [113 kB]
Fetched 113 kB in 1s (81.3 kB/s) 
Selecting previously unselected package strace.
(Reading database ... 11542 files and directories currently installed.)
Preparing to unpack .../strace_4.8-1ubuntu5_amd64.deb ...
Unpacking strace (4.8-1ubuntu5) ...
Setting up strace (4.8-1ubuntu5) ...
strace: test_ptrace_setoptions_for_all: PTRACE_TRACEME doesn't work: Operation not permitted
strace: test_ptrace_setoptions_for_all: unexpected exit status 1

Only “–privileded” option allow the container to use ptrace.

Is there any way to allow ptrace without using “privileged” flag ?

Output of docker version:

~$ docker version
Client:
 Version:      1.10.1
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   9e83765
 Built:        Thu Feb 11 19:14:21 2016
 OS/Arch:      darwin/amd64

Server:
 Version:      1.10.1
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   9e83765
 Built:        Thu Feb 11 19:32:54 2016
 OS/Arch:      linux/amd64

Output of docker info:

~$ docker info
Containers: 10
 Running: 8
 Paused: 0
 Stopped: 2
Images: 6
Server Version: 1.10.1
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 393
 Dirperm1 Supported: true
Execution Driver: native-0.2
Logging Driver: json-file
Plugins: 
 Volume: local
 Network: bridge null host
Kernel Version: 4.2.0-18-generic
Operating System: Ubuntu 15.10
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.858 GiB
Name: docker-node4
ID: U35M:LIYV:T5Q3:PMU5:UV4N:3QAS:I4ZA:YXQW:U23B:2RBK:E2GQ:L7BP
WARNING: No swap limit support
Labels:
 provider=amazonec2
~$ 

Provide additional environment details (AWS, VirtualBox, physical, etc.): Ubuntu14.04

List the steps to reproduce the issue:

  1. Run: $ docker run -i -t --cap-add=SYS_PTRACE --security-opt=apparmor:unconfined --rm ubuntu sh -c ‘apt-get install -y strace; strace /bin/ls’

Describe the results you received: strace: test_ptrace_setoptions_for_all: PTRACE_TRACEME doesn’t work: Operation not permitted

Describe the results you expected: strike result

Provide additional info you think is important:

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 17 (8 by maintainers)

Most upvoted comments

@itcreator Adding the following to the relevant container in my docker-compose.yml seems to work:

    cap_add:
    - SYS_PTRACE
    security_opt:
    - apparmor:unconfined

--cap-add SYS_PTRACE seems to be enough on Docker 18+:

Without the capability:

# docker run --rm -it --user 1000:1000 -v /usr/bin/strace:/usr/bin/strace  debian:stretch
I have no name!@4ece261cc10b:/$ sleep 1000 &
[1] 6
I have no name!@4ece261cc10b:/$ strace -p 6
strace: attach: ptrace(PTRACE_ATTACH, 6): Operation not permitted

With the capability:

# docker run --rm -it --user 1000:1000 -v /usr/bin/strace:/usr/bin/strace --cap-add SYS_PTRACE debian:stretch
I have no name!@8a42130c59d6:/$ sleep 1000 &
[1] 6
I have no name!@8a42130c59d6:/$ strace -p 6
strace: Process 6 attached
restart_syscall(<... resuming interrupted nanosleep ...>^Cstrace: Process 6 detached
 <detached ...>
I have no name!@8a42130c59d6:/$ cat /proc/self/status|grep Cap
CapInh: 00000000a80c25fb
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 00000000a80c25fb
CapAmb: 0000000000000000

As you see above, the process was running without the capability and it could still attach to the target process (which was running as the same unprivileged user). Due to adding the SYS_PTRACE capability on the command line, Docker configured seccomp without blocking the related syscalls (see the ptrace related section in the default seccomp profile: https://github.com/moby/moby/blob/master/profiles/seccomp/default.json)