Skip to content

Getting the system time with ntptime returns an error in an unprivileged container #33126

@miklosszegedi

Description

@miklosszegedi

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:

  1. Install Docker on CentOS 7 or Ubuntu 16. Run docker run -ti centos:7
  2. yum install -y ntp
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions