Description
I was able to repro this with ntptime. The command fails in a non-privileged Docker container.
strace ntptime
adjtimex is always called with modes=0:
adjtimex({modes=0, offset=-79766, freq=7440, maxerror=821262, esterror=1774, status=STA_PLL|STA_NANO, constant=9, precision=1, tolerance=32768000, time={1494361186, 267332645}, tick=10000, ppsfreq=0, jitter=0, shift=0, stabil=0, jitcnt=0, calcnt=0, errcnt=0, stbcnt=0}) = 0 (TIME_OK)...
The Linux kernel does not require CAP_SYS_TIME, if 'modes' is 0
https://github.com/torvalds/linux/blob/d33d5a6c88fcd53fec329a1521010f1bc55fa191/kernel/time/ntp.c
if (txc->modes & ADJ_ADJTIME) {
...
} else {
/* In order to modify anything, you gotta be super-user! */
if (txc->modes && !capable(CAP_SYS_TIME))
return -EPERM;
...
}
On the other hand the default Docker seccomp_default.go marks CAP_SYS_TIME as required for every call combination of adjtimex inputs instead of an allow entry for modes==0 regardless of CAP_SYS_TIME.
https://github.com/moby/moby/blob/master/profiles/seccomp/seccomp_default.go
{
Names: []string{
"settimeofday",
"stime",
"adjtimex",
"clock_settime",
},
Action: types.ActAllow,
Args: []*types.Arg{},
Includes: types.Filter{
Caps: []string{"CAP_SYS_TIME"},
},
},
Steps to reproduce the issue:
- Install Docker on CentOS 7 or Ubuntu 16. Run docker run -ti centos:7
- yum install -y ntp
- ntptime
Describe the results you received:
ntp_gettime() call fails: Operation not permitted
Must be root to set kernel values
ntp_adjtime() call fails: Operation not permitted
Describe the results you expected:
ntp_gettime() returns code 0 (OK)
time dcbcaa81.6bae1454 Tue, May 9 2017 20:52:17.420, (.420625175),
maximum error 481016 us, estimated error 1672 us, TAI offset 0
ntp_adjtime() returns code 0 (OK)
modes 0x0 (),
offset 328.412 us, frequency 0.157 ppm, interval 1 s,
maximum error 481016 us, estimated error 1672 us,
status 0x6001 (PLL,NANO,MODE),
time constant 10, precision 0.001 us, tolerance 500 ppm,
Additional information you deem important (e.g. issue happens only occasionally):
modes=0 shows a READ operation, not an adjustment as stated in the resolution of the related issue #16905. It should work in an unprivileged container.
Output of docker version:
Client:
Version: 1.12.6
API version: 1.24
Package version: docker-common-1.12.6-16.el7.centos.x86_64
Go version: go1.7.4
Git commit: 3a094bd/1.12.6
Built: Fri Apr 14 13:46:13 2017
OS/Arch: linux/amd64
Server:
Version: 1.12.6
API version: 1.24
Package version: docker-common-1.12.6-16.el7.centos.x86_64
Go version: go1.7.4
Git commit: 3a094bd/1.12.6
Built: Fri Apr 14 13:46:13 2017
OS/Arch: linux/amd64
Output of docker info:
Containers: 84
Running: 21
Paused: 0
Stopped: 63
Images: 71
Server Version: 1.12.6
Storage Driver: devicemapper
Pool Name: docker-8:1-654329922-pool
Pool Blocksize: 65.54 kB
Base Device Size: 10.74 GB
Backing Filesystem: xfs
Data file: /dev/loop0
Metadata file: /dev/loop1
Data Space Used: 5.546 GB
Data Space Total: 107.4 GB
Data Space Available: 98.22 GB
Metadata Space Used: 11.37 MB
Metadata Space Total: 2.147 GB
Metadata Space Available: 2.136 GB
Thin Pool Minimum Free Space: 10.74 GB
Udev Sync Supported: true
Deferred Removal Enabled: false
Deferred Deletion Enabled: false
Deferred Deleted Device Count: 0
Data loop file: /var/lib/docker/devicemapper/devicemapper/data
WARNING: Usage of loopback devices is strongly discouraged for production use. Use `--storage-opt dm.thinpooldev` to specify a custom block storage device.
Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata
Library Version: 1.02.135-RHEL7 (2016-11-16)
Logging Driver: journald
Cgroup Driver: systemd
Plugins:
Volume: local
Network: bridge overlay host null
Swarm: inactive
Runtimes: docker-runc runc
Default Runtime: docker-runc
Security Options: seccomp
Kernel Version: 3.10.0-514.2.2.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
Number of Docker Hooks: 2
CPUs: 1
Total Memory: 1.657 GiB
Name: host.example.com
ID: FO3J:AJ2R:RXSE:3B75:EMVA:IP2Y:ZKTZ:PCP2:CZSR:JLA7:BTQT:Y7M4
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Insecure Registries:
127.0.0.0/8
Registries: docker.io (secure)
Additional environment details (AWS, VirtualBox, physical, etc.):
GCE VM
Description
I was able to repro this with ntptime. The command fails in a non-privileged Docker container.
strace ntptime
adjtimex is always called with modes=0:
The Linux kernel does not require CAP_SYS_TIME, if 'modes' is 0
https://github.com/torvalds/linux/blob/d33d5a6c88fcd53fec329a1521010f1bc55fa191/kernel/time/ntp.c
On the other hand the default Docker
seccomp_default.gomarksCAP_SYS_TIMEas required for every call combination of adjtimex inputs instead of an allow entry formodes==0regardless ofCAP_SYS_TIME.https://github.com/moby/moby/blob/master/profiles/seccomp/seccomp_default.go
Steps to reproduce the issue:
Describe the results you received:
Describe the results you expected:
Additional information you deem important (e.g. issue happens only occasionally):
modes=0shows a READ operation, not an adjustment as stated in the resolution of the related issue #16905. It should work in an unprivileged container.Output of
docker version:Output of
docker info:Additional environment details (AWS, VirtualBox, physical, etc.):
GCE VM