Browse code

Align default seccomp profile with selected capabilities

Currently the default seccomp profile is fixed. This changes it
so that it varies depending on the Linux capabilities selected with
the --cap-add and --cap-drop options. Without this, if a user adds
privileges, eg to allow ptrace with --cap-add sys_ptrace then still
cannot actually use ptrace as it is still blocked by seccomp, so
they will probably disable seccomp or use --privileged. With this
change the syscalls that are needed for the capability are also
allowed by the seccomp profile based on the selected capabilities.

While this patch makes it easier to do things with for example
cap_sys_admin enabled, as it will now allow creating new namespaces
and use of mount, it still allows less than --cap-add cap_sys_admin
--security-opt seccomp:unconfined would have previously. It is not
recommended that users run containers with cap_sys_admin as this does
give full access to the host machine.

It also cleans up some architecture specific system calls to be
only selected when needed.

Signed-off-by: Justin Cormack <justin.cormack@docker.com>

Justin Cormack authored on 2016/05/06 23:17:41
Showing 8 changed files
... ...
@@ -35,7 +35,7 @@ func setSeccomp(daemon *Daemon, rs *specs.Spec, c *container.Container) error {
35 35
 			return err
36 36
 		}
37 37
 	} else {
38
-		profile, err = seccomp.GetDefaultProfile()
38
+		profile, err = seccomp.GetDefaultProfile(rs)
39 39
 		if err != nil {
40 40
 			return err
41 41
 		}
... ...
@@ -1071,14 +1071,6 @@ one can use this flag:
1071 1071
     --privileged=false: Give extended privileges to this container
1072 1072
     --device=[]: Allows you to run devices inside the container without the --privileged flag.
1073 1073
 
1074
-> **Note:**
1075
-> With Docker 1.10 and greater, the default seccomp profile will also block
1076
-> syscalls, regardless of `--cap-add` passed to the container. We recommend in
1077
-> these cases to create your own custom seccomp profile based off our
1078
-> [default](https://github.com/docker/docker/blob/master/profiles/seccomp/default.json).
1079
-> Or if you don't want to run with the default seccomp profile, you can pass
1080
-> `--security-opt=seccomp=unconfined` on run.
1081
-
1082 1074
 By default, Docker containers are "unprivileged" and cannot, for
1083 1075
 example, run a Docker daemon inside a Docker container. This is because
1084 1076
 by default a container is not allowed to access any devices, but a
... ...
@@ -1196,6 +1188,11 @@ To mount a FUSE based filesystem, you need to combine both `--cap-add` and
1196 1196
     -rw-rw-r-- 1 1000 1000    461 Dec  4 06:08 .gitignore
1197 1197
     ....
1198 1198
 
1199
+The default seccomp profile will adjust to the selected capabilities, in order to allow
1200
+use of facilities allowed by the capabilities, so you should not have to adjust this,
1201
+since Docker 1.12. In Docker 1.10 and 1.11 this did not happen and it may be necessary
1202
+to use a custom seccomp profile or use `--security-opt seccomp=unconfined` when adding
1203
+capabilities.
1199 1204
 
1200 1205
 ## Logging drivers (--log-driver)
1201 1206
 
... ...
@@ -948,10 +948,10 @@ func (s *DockerSuite) TestRunSeccompDefaultProfile(c *check.C) {
948 948
 	testRequires(c, SameHostDaemon, seccompEnabled, NotUserNamespace)
949 949
 
950 950
 	var group sync.WaitGroup
951
-	group.Add(4)
951
+	group.Add(11)
952 952
 	errChan := make(chan error, 4)
953 953
 	go func() {
954
-		out, _, err := dockerCmdWithError("run", "--cap-add", "ALL", "syscall-test", "acct-test")
954
+		out, _, err := dockerCmdWithError("run", "syscall-test", "acct-test")
955 955
 		if err == nil || !strings.Contains(out, "Operation not permitted") {
956 956
 			errChan <- fmt.Errorf("expected Operation not permitted, got: %s", out)
957 957
 		}
... ...
@@ -959,7 +959,7 @@ func (s *DockerSuite) TestRunSeccompDefaultProfile(c *check.C) {
959 959
 	}()
960 960
 
961 961
 	go func() {
962
-		out, _, err := dockerCmdWithError("run", "--cap-add", "ALL", "syscall-test", "ns-test", "echo", "hello")
962
+		out, _, err := dockerCmdWithError("run", "--cap-add", "sys_admin", "syscall-test", "acct-test")
963 963
 		if err == nil || !strings.Contains(out, "Operation not permitted") {
964 964
 			errChan <- fmt.Errorf("expected Operation not permitted, got: %s", out)
965 965
 		}
... ...
@@ -967,6 +967,62 @@ func (s *DockerSuite) TestRunSeccompDefaultProfile(c *check.C) {
967 967
 	}()
968 968
 
969 969
 	go func() {
970
+		out, _, err := dockerCmdWithError("run", "--cap-add", "sys_pacct", "syscall-test", "acct-test")
971
+		if err == nil || !strings.Contains(out, "No such file or directory") {
972
+			errChan <- fmt.Errorf("expected No such file or directory, got: %s", out)
973
+		}
974
+		group.Done()
975
+	}()
976
+
977
+	go func() {
978
+		out, _, err := dockerCmdWithError("run", "--cap-add", "ALL", "syscall-test", "acct-test")
979
+		if err == nil || !strings.Contains(out, "No such file or directory") {
980
+			errChan <- fmt.Errorf("expected No such file or directory, got: %s", out)
981
+		}
982
+		group.Done()
983
+	}()
984
+
985
+	go func() {
986
+		out, _, err := dockerCmdWithError("run", "--cap-drop", "ALL", "--cap-add", "sys_pacct", "syscall-test", "acct-test")
987
+		if err == nil || !strings.Contains(out, "No such file or directory") {
988
+			errChan <- fmt.Errorf("expected No such file or directory, got: %s", out)
989
+		}
990
+		group.Done()
991
+	}()
992
+
993
+	go func() {
994
+		out, _, err := dockerCmdWithError("run", "syscall-test", "ns-test", "echo", "hello0")
995
+		if err == nil || !strings.Contains(out, "Operation not permitted") {
996
+			errChan <- fmt.Errorf("expected Operation not permitted, got: %s", out)
997
+		}
998
+		group.Done()
999
+	}()
1000
+
1001
+	go func() {
1002
+		out, _, err := dockerCmdWithError("run", "--cap-add", "sys_admin", "syscall-test", "ns-test", "echo", "hello1")
1003
+		if err != nil || !strings.Contains(out, "hello1") {
1004
+			errChan <- fmt.Errorf("expected hello1, got: %s, %v", out, err)
1005
+		}
1006
+		group.Done()
1007
+	}()
1008
+
1009
+	go func() {
1010
+		out, _, err := dockerCmdWithError("run", "--cap-drop", "all", "--cap-add", "sys_admin", "syscall-test", "ns-test", "echo", "hello2")
1011
+		if err != nil || !strings.Contains(out, "hello2") {
1012
+			errChan <- fmt.Errorf("expected hello2, got: %s, %v", out, err)
1013
+		}
1014
+		group.Done()
1015
+	}()
1016
+
1017
+	go func() {
1018
+		out, _, err := dockerCmdWithError("run", "--cap-add", "ALL", "syscall-test", "ns-test", "echo", "hello3")
1019
+		if err != nil || !strings.Contains(out, "hello3") {
1020
+			errChan <- fmt.Errorf("expected hello3, got: %s, %v", out, err)
1021
+		}
1022
+		group.Done()
1023
+	}()
1024
+
1025
+	go func() {
970 1026
 		out, _, err := dockerCmdWithError("run", "--cap-add", "ALL", "--security-opt", "seccomp=unconfined", "syscall-test", "acct-test")
971 1027
 		if err == nil || !strings.Contains(out, "No such file or directory") {
972 1028
 			errChan <- fmt.Errorf("expected No such file or directory, got: %s", out)
... ...
@@ -975,9 +1031,9 @@ func (s *DockerSuite) TestRunSeccompDefaultProfile(c *check.C) {
975 975
 	}()
976 976
 
977 977
 	go func() {
978
-		out, _, err := dockerCmdWithError("run", "--cap-add", "ALL", "--security-opt", "seccomp=unconfined", "syscall-test", "ns-test", "echo", "hello")
979
-		if err != nil || !strings.Contains(out, "hello") {
980
-			errChan <- fmt.Errorf("expected hello, got: %s, %v", out, err)
978
+		out, _, err := dockerCmdWithError("run", "--cap-add", "ALL", "--security-opt", "seccomp=unconfined", "syscall-test", "ns-test", "echo", "hello4")
979
+		if err != nil || !strings.Contains(out, "hello4") {
980
+			errChan <- fmt.Errorf("expected hello4, got: %s, %v", out, err)
981 981
 		}
982 982
 		group.Done()
983 983
 	}()
... ...
@@ -27,11 +27,6 @@
27 27
 			"args": []
28 28
 		},
29 29
 		{
30
-			"name": "arch_prctl",
31
-			"action": "SCMP_ACT_ALLOW",
32
-			"args": []
33
-		},
34
-		{
35 30
 			"name": "bind",
36 31
 			"action": "SCMP_ACT_ALLOW",
37 32
 			"args": []
... ...
@@ -62,21 +57,6 @@
62 62
 			"args": []
63 63
 		},
64 64
 		{
65
-			"name": "chown",
66
-			"action": "SCMP_ACT_ALLOW",
67
-			"args": []
68
-		},
69
-		{
70
-			"name": "chown32",
71
-			"action": "SCMP_ACT_ALLOW",
72
-			"args": []
73
-		},
74
-		{
75
-			"name": "chroot",
76
-			"action": "SCMP_ACT_ALLOW",
77
-			"args": []
78
-		},
79
-		{
80 65
 			"name": "clock_getres",
81 66
 			"action": "SCMP_ACT_ALLOW",
82 67
 			"args": []
... ...
@@ -92,18 +72,6 @@
92 92
 			"args": []
93 93
 		},
94 94
 		{
95
-			"name": "clone",
96
-			"action": "SCMP_ACT_ALLOW",
97
-			"args": [
98
-				{
99
-					"index": 0,
100
-					"value": 2080505856,
101
-					"valueTwo": 0,
102
-					"op": "SCMP_CMP_MASKED_EQ"
103
-				}
104
-			]
105
-		},
106
-		{
107 95
 			"name": "close",
108 96
 			"action": "SCMP_ACT_ALLOW",
109 97
 			"args": []
... ...
@@ -224,11 +192,6 @@
224 224
 			"args": []
225 225
 		},
226 226
 		{
227
-			"name": "fanotify_init",
228
-			"action": "SCMP_ACT_ALLOW",
229
-			"args": []
230
-		},
231
-		{
232 227
 			"name": "fanotify_mark",
233 228
 			"action": "SCMP_ACT_ALLOW",
234 229
 			"args": []
... ...
@@ -249,21 +212,6 @@
249 249
 			"args": []
250 250
 		},
251 251
 		{
252
-			"name": "fchown",
253
-			"action": "SCMP_ACT_ALLOW",
254
-			"args": []
255
-		},
256
-		{
257
-			"name": "fchown32",
258
-			"action": "SCMP_ACT_ALLOW",
259
-			"args": []
260
-		},
261
-		{
262
-			"name": "fchownat",
263
-			"action": "SCMP_ACT_ALLOW",
264
-			"args": []
265
-		},
266
-		{
267 252
 			"name": "fcntl",
268 253
 			"action": "SCMP_ACT_ALLOW",
269 254
 			"args": []
... ...
@@ -609,16 +557,6 @@
609 609
 			"args": []
610 610
 		},
611 611
 		{
612
-			"name": "lchown",
613
-			"action": "SCMP_ACT_ALLOW",
614
-			"args": []
615
-		},
616
-		{
617
-			"name": "lchown32",
618
-			"action": "SCMP_ACT_ALLOW",
619
-			"args": []
620
-		},
621
-		{
622 612
 			"name": "lgetxattr",
623 613
 			"action": "SCMP_ACT_ALLOW",
624 614
 			"args": []
... ...
@@ -1165,11 +1103,6 @@
1165 1165
 			"args": []
1166 1166
 		},
1167 1167
 		{
1168
-			"name": "setdomainname",
1169
-			"action": "SCMP_ACT_ALLOW",
1170
-			"args": []
1171
-		},
1172
-		{
1173 1168
 			"name": "setfsgid",
1174 1169
 			"action": "SCMP_ACT_ALLOW",
1175 1170
 			"args": []
... ...
@@ -1210,11 +1143,6 @@
1210 1210
 			"args": []
1211 1211
 		},
1212 1212
 		{
1213
-			"name": "sethostname",
1214
-			"action": "SCMP_ACT_ALLOW",
1215
-			"args": []
1216
-		},
1217
-		{
1218 1213
 			"name": "setitimer",
1219 1214
 			"action": "SCMP_ACT_ALLOW",
1220 1215
 			"args": []
... ...
@@ -1580,22 +1508,69 @@
1580 1580
 			"args": []
1581 1581
 		},
1582 1582
 		{
1583
+			"name": "arch_prctl",
1584
+			"action": "SCMP_ACT_ALLOW",
1585
+			"args": []
1586
+		},
1587
+		{
1583 1588
 			"name": "modify_ldt",
1584 1589
 			"action": "SCMP_ACT_ALLOW",
1585 1590
 			"args": []
1586 1591
 		},
1587 1592
 		{
1588
-			"name": "breakpoint",
1593
+			"name": "chown",
1594
+			"action": "SCMP_ACT_ALLOW",
1595
+			"args": []
1596
+		},
1597
+		{
1598
+			"name": "chown32",
1589 1599
 			"action": "SCMP_ACT_ALLOW",
1590 1600
 			"args": []
1591 1601
 		},
1592 1602
 		{
1593
-			"name": "cacheflush",
1603
+			"name": "fchown",
1594 1604
 			"action": "SCMP_ACT_ALLOW",
1595 1605
 			"args": []
1596 1606
 		},
1597 1607
 		{
1598
-			"name": "set_tls",
1608
+			"name": "fchown32",
1609
+			"action": "SCMP_ACT_ALLOW",
1610
+			"args": []
1611
+		},
1612
+		{
1613
+			"name": "fchownat",
1614
+			"action": "SCMP_ACT_ALLOW",
1615
+			"args": []
1616
+		},
1617
+		{
1618
+			"name": "lchown",
1619
+			"action": "SCMP_ACT_ALLOW",
1620
+			"args": []
1621
+		},
1622
+		{
1623
+			"name": "lchown32",
1624
+			"action": "SCMP_ACT_ALLOW",
1625
+			"args": []
1626
+		},
1627
+		{
1628
+			"name": "chroot",
1629
+			"action": "SCMP_ACT_ALLOW",
1630
+			"args": []
1631
+		},
1632
+		{
1633
+			"name": "clone",
1634
+			"action": "SCMP_ACT_ALLOW",
1635
+			"args": [
1636
+				{
1637
+					"index": 0,
1638
+					"value": 2080505856,
1639
+					"valueTwo": 0,
1640
+					"op": "SCMP_CMP_MASKED_EQ"
1641
+				}
1642
+			]
1643
+		},
1644
+		{
1645
+			"name": "fchown",
1599 1646
 			"action": "SCMP_ACT_ALLOW",
1600 1647
 			"args": []
1601 1648
 		}
... ...
@@ -8,6 +8,7 @@ import (
8 8
 	"os"
9 9
 	"path/filepath"
10 10
 
11
+	"github.com/docker/docker/oci"
11 12
 	"github.com/docker/docker/profiles/seccomp"
12 13
 )
13 14
 
... ...
@@ -20,8 +21,10 @@ func main() {
20 20
 	}
21 21
 	f := filepath.Join(wd, "default.json")
22 22
 
23
+	rs := oci.DefaultSpec()
24
+
23 25
 	// write the default profile to the file
24
-	b, err := json.MarshalIndent(seccomp.DefaultProfile, "", "\t")
26
+	b, err := json.MarshalIndent(seccomp.DefaultProfile(&rs), "", "\t")
25 27
 	if err != nil {
26 28
 		panic(err)
27 29
 	}
... ...
@@ -13,8 +13,8 @@ import (
13 13
 //go:generate go run -tags 'seccomp' generate.go
14 14
 
15 15
 // GetDefaultProfile returns the default seccomp profile.
16
-func GetDefaultProfile() (*specs.Seccomp, error) {
17
-	return setupSeccomp(DefaultProfile)
16
+func GetDefaultProfile(rs *specs.Spec) (*specs.Seccomp, error) {
17
+	return setupSeccomp(DefaultProfile(rs))
18 18
 }
19 19
 
20 20
 // LoadProfile takes a file path and decodes the seccomp profile.
... ...
@@ -6,6 +6,7 @@ import (
6 6
 	"syscall"
7 7
 
8 8
 	"github.com/docker/engine-api/types"
9
+	"github.com/opencontainers/specs/specs-go"
9 10
 	libseccomp "github.com/seccomp/libseccomp-golang"
10 11
 )
11 12
 
... ...
@@ -34,10 +35,9 @@ func arches() []types.Arch {
34 34
 }
35 35
 
36 36
 // DefaultProfile defines the whitelist for the default seccomp profile.
37
-var DefaultProfile = &types.Seccomp{
38
-	DefaultAction: types.ActErrno,
39
-	Architectures: arches(),
40
-	Syscalls: []*types.Syscall{
37
+func DefaultProfile(rs *specs.Spec) *types.Seccomp {
38
+
39
+	syscalls := []*types.Syscall{
41 40
 		{
42 41
 			Name:   "accept",
43 42
 			Action: types.ActAllow,
... ...
@@ -59,11 +59,6 @@ var DefaultProfile = &types.Seccomp{
59 59
 			Args:   []*types.Arg{},
60 60
 		},
61 61
 		{
62
-			Name:   "arch_prctl",
63
-			Action: types.ActAllow,
64
-			Args:   []*types.Arg{},
65
-		},
66
-		{
67 62
 			Name:   "bind",
68 63
 			Action: types.ActAllow,
69 64
 			Args:   []*types.Arg{},
... ...
@@ -94,21 +89,6 @@ var DefaultProfile = &types.Seccomp{
94 94
 			Args:   []*types.Arg{},
95 95
 		},
96 96
 		{
97
-			Name:   "chown",
98
-			Action: types.ActAllow,
99
-			Args:   []*types.Arg{},
100
-		},
101
-		{
102
-			Name:   "chown32",
103
-			Action: types.ActAllow,
104
-			Args:   []*types.Arg{},
105
-		},
106
-		{
107
-			Name:   "chroot",
108
-			Action: types.ActAllow,
109
-			Args:   []*types.Arg{},
110
-		},
111
-		{
112 97
 			Name:   "clock_getres",
113 98
 			Action: types.ActAllow,
114 99
 			Args:   []*types.Arg{},
... ...
@@ -124,18 +104,6 @@ var DefaultProfile = &types.Seccomp{
124 124
 			Args:   []*types.Arg{},
125 125
 		},
126 126
 		{
127
-			Name:   "clone",
128
-			Action: types.ActAllow,
129
-			Args: []*types.Arg{
130
-				{
131
-					Index:    0,
132
-					Value:    syscall.CLONE_NEWNS | syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWUSER | syscall.CLONE_NEWPID | syscall.CLONE_NEWNET,
133
-					ValueTwo: 0,
134
-					Op:       types.OpMaskedEqual,
135
-				},
136
-			},
137
-		},
138
-		{
139 127
 			Name:   "close",
140 128
 			Action: types.ActAllow,
141 129
 			Args:   []*types.Arg{},
... ...
@@ -256,11 +224,6 @@ var DefaultProfile = &types.Seccomp{
256 256
 			Args:   []*types.Arg{},
257 257
 		},
258 258
 		{
259
-			Name:   "fanotify_init",
260
-			Action: types.ActAllow,
261
-			Args:   []*types.Arg{},
262
-		},
263
-		{
264 259
 			Name:   "fanotify_mark",
265 260
 			Action: types.ActAllow,
266 261
 			Args:   []*types.Arg{},
... ...
@@ -281,21 +244,6 @@ var DefaultProfile = &types.Seccomp{
281 281
 			Args:   []*types.Arg{},
282 282
 		},
283 283
 		{
284
-			Name:   "fchown",
285
-			Action: types.ActAllow,
286
-			Args:   []*types.Arg{},
287
-		},
288
-		{
289
-			Name:   "fchown32",
290
-			Action: types.ActAllow,
291
-			Args:   []*types.Arg{},
292
-		},
293
-		{
294
-			Name:   "fchownat",
295
-			Action: types.ActAllow,
296
-			Args:   []*types.Arg{},
297
-		},
298
-		{
299 284
 			Name:   "fcntl",
300 285
 			Action: types.ActAllow,
301 286
 			Args:   []*types.Arg{},
... ...
@@ -641,16 +589,6 @@ var DefaultProfile = &types.Seccomp{
641 641
 			Args:   []*types.Arg{},
642 642
 		},
643 643
 		{
644
-			Name:   "lchown",
645
-			Action: types.ActAllow,
646
-			Args:   []*types.Arg{},
647
-		},
648
-		{
649
-			Name:   "lchown32",
650
-			Action: types.ActAllow,
651
-			Args:   []*types.Arg{},
652
-		},
653
-		{
654 644
 			Name:   "lgetxattr",
655 645
 			Action: types.ActAllow,
656 646
 			Args:   []*types.Arg{},
... ...
@@ -1194,11 +1132,6 @@ var DefaultProfile = &types.Seccomp{
1194 1194
 			Args:   []*types.Arg{},
1195 1195
 		},
1196 1196
 		{
1197
-			Name:   "setdomainname",
1198
-			Action: types.ActAllow,
1199
-			Args:   []*types.Arg{},
1200
-		},
1201
-		{
1202 1197
 			Name:   "setfsgid",
1203 1198
 			Action: types.ActAllow,
1204 1199
 			Args:   []*types.Arg{},
... ...
@@ -1239,11 +1172,6 @@ var DefaultProfile = &types.Seccomp{
1239 1239
 			Args:   []*types.Arg{},
1240 1240
 		},
1241 1241
 		{
1242
-			Name:   "sethostname",
1243
-			Action: types.ActAllow,
1244
-			Args:   []*types.Arg{},
1245
-		},
1246
-		{
1247 1242
 			Name:   "setitimer",
1248 1243
 			Action: types.ActAllow,
1249 1244
 			Args:   []*types.Arg{},
... ...
@@ -1608,27 +1536,332 @@ var DefaultProfile = &types.Seccomp{
1608 1608
 			Action: types.ActAllow,
1609 1609
 			Args:   []*types.Arg{},
1610 1610
 		},
1611
-		// i386 specific syscalls
1612
-		{
1613
-			Name:   "modify_ldt",
1614
-			Action: types.ActAllow,
1615
-			Args:   []*types.Arg{},
1616
-		},
1617
-		// arm specific syscalls
1618
-		{
1619
-			Name:   "breakpoint",
1620
-			Action: types.ActAllow,
1621
-			Args:   []*types.Arg{},
1622
-		},
1623
-		{
1624
-			Name:   "cacheflush",
1625
-			Action: types.ActAllow,
1626
-			Args:   []*types.Arg{},
1627
-		},
1628
-		{
1629
-			Name:   "set_tls",
1630
-			Action: types.ActAllow,
1631
-			Args:   []*types.Arg{},
1632
-		},
1633
-	},
1611
+	}
1612
+
1613
+	var arch string
1614
+	var native, err = libseccomp.GetNativeArch()
1615
+	if err == nil {
1616
+		arch = native.String()
1617
+	}
1618
+	switch arch {
1619
+	case "arm", "arm64":
1620
+		syscalls = append(syscalls, []*types.Syscall{
1621
+			{
1622
+				Name:   "breakpoint",
1623
+				Action: types.ActAllow,
1624
+				Args:   []*types.Arg{},
1625
+			},
1626
+			{
1627
+				Name:   "cacheflush",
1628
+				Action: types.ActAllow,
1629
+				Args:   []*types.Arg{},
1630
+			},
1631
+			{
1632
+				Name:   "set_tls",
1633
+				Action: types.ActAllow,
1634
+				Args:   []*types.Arg{},
1635
+			},
1636
+		}...)
1637
+	case "amd64", "x32":
1638
+		syscalls = append(syscalls, []*types.Syscall{
1639
+			{
1640
+				Name:   "arch_prctl",
1641
+				Action: types.ActAllow,
1642
+				Args:   []*types.Arg{},
1643
+			},
1644
+		}...)
1645
+		fallthrough
1646
+	case "x86":
1647
+		syscalls = append(syscalls, []*types.Syscall{
1648
+			{
1649
+				Name:   "modify_ldt",
1650
+				Action: types.ActAllow,
1651
+				Args:   []*types.Arg{},
1652
+			},
1653
+		}...)
1654
+	}
1655
+
1656
+	capSysAdmin := false
1657
+
1658
+	var cap string
1659
+	for _, cap = range rs.Process.Capabilities {
1660
+		switch cap {
1661
+		case "CAP_CHOWN":
1662
+			syscalls = append(syscalls, []*types.Syscall{
1663
+				{
1664
+					Name:   "chown",
1665
+					Action: types.ActAllow,
1666
+					Args:   []*types.Arg{},
1667
+				},
1668
+				{
1669
+					Name:   "chown32",
1670
+					Action: types.ActAllow,
1671
+					Args:   []*types.Arg{},
1672
+				},
1673
+				{
1674
+					Name:   "fchown",
1675
+					Action: types.ActAllow,
1676
+					Args:   []*types.Arg{},
1677
+				},
1678
+				{
1679
+					Name:   "fchown32",
1680
+					Action: types.ActAllow,
1681
+					Args:   []*types.Arg{},
1682
+				},
1683
+				{
1684
+					Name:   "fchownat",
1685
+					Action: types.ActAllow,
1686
+					Args:   []*types.Arg{},
1687
+				},
1688
+				{
1689
+					Name:   "lchown",
1690
+					Action: types.ActAllow,
1691
+					Args:   []*types.Arg{},
1692
+				},
1693
+				{
1694
+					Name:   "lchown32",
1695
+					Action: types.ActAllow,
1696
+					Args:   []*types.Arg{},
1697
+				},
1698
+			}...)
1699
+		case "CAP_DAC_READ_SEARCH":
1700
+			syscalls = append(syscalls, []*types.Syscall{
1701
+				{
1702
+					Name:   "name_to_handle_at",
1703
+					Action: types.ActAllow,
1704
+					Args:   []*types.Arg{},
1705
+				},
1706
+				{
1707
+					Name:   "open_by_handle_at",
1708
+					Action: types.ActAllow,
1709
+					Args:   []*types.Arg{},
1710
+				},
1711
+			}...)
1712
+		case "CAP_IPC_LOCK":
1713
+			syscalls = append(syscalls, []*types.Syscall{
1714
+				{
1715
+					Name:   "mlock",
1716
+					Action: types.ActAllow,
1717
+					Args:   []*types.Arg{},
1718
+				},
1719
+				{
1720
+					Name:   "mlock2",
1721
+					Action: types.ActAllow,
1722
+					Args:   []*types.Arg{},
1723
+				},
1724
+				{
1725
+					Name:   "mlockall",
1726
+					Action: types.ActAllow,
1727
+					Args:   []*types.Arg{},
1728
+				},
1729
+			}...)
1730
+		case "CAP_SYS_ADMIN":
1731
+			capSysAdmin = true
1732
+			syscalls = append(syscalls, []*types.Syscall{
1733
+				{
1734
+					Name:   "bpf",
1735
+					Action: types.ActAllow,
1736
+					Args:   []*types.Arg{},
1737
+				},
1738
+				{
1739
+					Name:   "clone",
1740
+					Action: types.ActAllow,
1741
+					Args:   []*types.Arg{},
1742
+				},
1743
+				{
1744
+					Name:   "fanotify_init",
1745
+					Action: types.ActAllow,
1746
+					Args:   []*types.Arg{},
1747
+				},
1748
+				{
1749
+					Name:   "lookup_dcookie",
1750
+					Action: types.ActAllow,
1751
+					Args:   []*types.Arg{},
1752
+				},
1753
+				{
1754
+					Name:   "mount",
1755
+					Action: types.ActAllow,
1756
+					Args:   []*types.Arg{},
1757
+				},
1758
+				{
1759
+					Name:   "perf_event_open",
1760
+					Action: types.ActAllow,
1761
+					Args:   []*types.Arg{},
1762
+				},
1763
+				{
1764
+					Name:   "setdomainname",
1765
+					Action: types.ActAllow,
1766
+					Args:   []*types.Arg{},
1767
+				},
1768
+				{
1769
+					Name:   "sethostname",
1770
+					Action: types.ActAllow,
1771
+					Args:   []*types.Arg{},
1772
+				},
1773
+				{
1774
+					Name:   "setns",
1775
+					Action: types.ActAllow,
1776
+					Args:   []*types.Arg{},
1777
+				},
1778
+				{
1779
+					Name:   "umount",
1780
+					Action: types.ActAllow,
1781
+					Args:   []*types.Arg{},
1782
+				},
1783
+				{
1784
+					Name:   "umount2",
1785
+					Action: types.ActAllow,
1786
+					Args:   []*types.Arg{},
1787
+				},
1788
+				{
1789
+					Name:   "unshare",
1790
+					Action: types.ActAllow,
1791
+					Args:   []*types.Arg{},
1792
+				},
1793
+			}...)
1794
+		case "CAP_SYS_BOOT":
1795
+			syscalls = append(syscalls, []*types.Syscall{
1796
+				{
1797
+					Name:   "reboot",
1798
+					Action: types.ActAllow,
1799
+					Args:   []*types.Arg{},
1800
+				},
1801
+			}...)
1802
+		case "CAP_SYS_CHROOT":
1803
+			syscalls = append(syscalls, []*types.Syscall{
1804
+				{
1805
+					Name:   "chroot",
1806
+					Action: types.ActAllow,
1807
+					Args:   []*types.Arg{},
1808
+				},
1809
+			}...)
1810
+		case "CAP_SYS_MODULE":
1811
+			syscalls = append(syscalls, []*types.Syscall{
1812
+				{
1813
+					Name:   "delete_module",
1814
+					Action: types.ActAllow,
1815
+					Args:   []*types.Arg{},
1816
+				},
1817
+				{
1818
+					Name:   "init_module",
1819
+					Action: types.ActAllow,
1820
+					Args:   []*types.Arg{},
1821
+				},
1822
+				{
1823
+					Name:   "finit_module",
1824
+					Action: types.ActAllow,
1825
+					Args:   []*types.Arg{},
1826
+				},
1827
+				{
1828
+					Name:   "query_module",
1829
+					Action: types.ActAllow,
1830
+					Args:   []*types.Arg{},
1831
+				},
1832
+			}...)
1833
+		case "CAP_SYS_PACCT":
1834
+			syscalls = append(syscalls, []*types.Syscall{
1835
+				{
1836
+					Name:   "acct",
1837
+					Action: types.ActAllow,
1838
+					Args:   []*types.Arg{},
1839
+				},
1840
+			}...)
1841
+		case "CAP_SYS_PTRACE":
1842
+			syscalls = append(syscalls, []*types.Syscall{
1843
+				{
1844
+					Name:   "kcmp",
1845
+					Action: types.ActAllow,
1846
+					Args:   []*types.Arg{},
1847
+				},
1848
+				{
1849
+					Name:   "process_vm_readv",
1850
+					Action: types.ActAllow,
1851
+					Args:   []*types.Arg{},
1852
+				},
1853
+				{
1854
+					Name:   "process_vm_writev",
1855
+					Action: types.ActAllow,
1856
+					Args:   []*types.Arg{},
1857
+				},
1858
+				{
1859
+					Name:   "ptrace",
1860
+					Action: types.ActAllow,
1861
+					Args:   []*types.Arg{},
1862
+				},
1863
+			}...)
1864
+		case "CAP_SYS_RAWIO":
1865
+			syscalls = append(syscalls, []*types.Syscall{
1866
+				{
1867
+					Name:   "iopl",
1868
+					Action: types.ActAllow,
1869
+					Args:   []*types.Arg{},
1870
+				},
1871
+				{
1872
+					Name:   "ioperm",
1873
+					Action: types.ActAllow,
1874
+					Args:   []*types.Arg{},
1875
+				},
1876
+			}...)
1877
+		case "CAP_SYS_TIME":
1878
+			syscalls = append(syscalls, []*types.Syscall{
1879
+				{
1880
+					Name:   "settimeofday",
1881
+					Action: types.ActAllow,
1882
+					Args:   []*types.Arg{},
1883
+				},
1884
+				{
1885
+					Name:   "stime",
1886
+					Action: types.ActAllow,
1887
+					Args:   []*types.Arg{},
1888
+				},
1889
+				{
1890
+					Name:   "adjtimex",
1891
+					Action: types.ActAllow,
1892
+					Args:   []*types.Arg{},
1893
+				},
1894
+			}...)
1895
+		case "CAP_SYS_TTY_CONFIG":
1896
+			syscalls = append(syscalls, []*types.Syscall{
1897
+				{
1898
+					Name:   "vhangup",
1899
+					Action: types.ActAllow,
1900
+					Args:   []*types.Arg{},
1901
+				},
1902
+			}...)
1903
+		}
1904
+	}
1905
+
1906
+	if !capSysAdmin {
1907
+		syscalls = append(syscalls, []*types.Syscall{
1908
+			{
1909
+				Name:   "clone",
1910
+				Action: types.ActAllow,
1911
+				Args: []*types.Arg{
1912
+					{
1913
+						Index:    0,
1914
+						Value:    syscall.CLONE_NEWNS | syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWUSER | syscall.CLONE_NEWPID | syscall.CLONE_NEWNET,
1915
+						ValueTwo: 0,
1916
+						Op:       types.OpMaskedEqual,
1917
+					},
1918
+				},
1919
+			},
1920
+		}...)
1921
+	}
1922
+
1923
+	// We need some additional syscalls in this case see #22252
1924
+	if !rs.Process.NoNewPrivileges {
1925
+		syscalls = append(syscalls, []*types.Syscall{
1926
+			{
1927
+				Name:   "fchown",
1928
+				Action: types.ActAllow,
1929
+				Args:   []*types.Arg{},
1930
+			},
1931
+		}...)
1932
+	}
1933
+
1934
+	return &types.Seccomp{
1935
+		DefaultAction: types.ActErrno,
1936
+		Architectures: arches(),
1937
+		Syscalls:      syscalls,
1938
+	}
1634 1939
 }
... ...
@@ -2,9 +2,12 @@
2 2
 
3 3
 package seccomp
4 4
 
5
-import "github.com/docker/engine-api/types"
6
-
7
-var (
8
-	// DefaultProfile is a nil pointer on unsupported systems.
9
-	DefaultProfile *types.Seccomp
5
+import (
6
+	"github.com/docker/engine-api/types"
7
+	"github.com/opencontainers/specs/specs-go"
10 8
 )
9
+
10
+// DefaultProfile returns a nil pointer on unsupported systems.
11
+func DefaultProfile(rs *specs.Spec) *types.Seccomp {
12
+	return nil
13
+}