Browse code

Capabilities refactor - Add support for exact list of capabilities, support only OCI model - Support OCI model on CapAdd and CapDrop but remain backward compatibility - Create variable locally instead of declaring it at the top - Use const for magic "ALL" value - Rename `cap` variable as it overlaps with `cap()` built-in - Normalize and validate capabilities before use - Move validation for conflicting options to validateHostConfig() - TweakCapabilities: simplify logic to calculate capabilities

Signed-off-by: Olli Janatuinen <olli.janatuinen@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Olli Janatuinen authored on 2018/12/17 00:11:37
Showing 12 changed files
... ...
@@ -473,6 +473,11 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
473 473
 		hostConfig.KernelMemoryTCP = 0
474 474
 	}
475 475
 
476
+	// Ignore Capabilities because it was added in API 1.40.
477
+	if hostConfig != nil && versions.LessThan(version, "1.40") {
478
+		hostConfig.Capabilities = nil
479
+	}
480
+
476 481
 	ccr, err := s.backend.ContainerCreate(types.ContainerCreateConfig{
477 482
 		Name:             name,
478 483
 		Config:           config,
... ...
@@ -645,14 +645,22 @@ definitions:
645 645
               $ref: "#/definitions/Mount"
646 646
 
647 647
           # Applicable to UNIX platforms
648
+          Capabilities:
649
+            type: "array"
650
+            description: |
651
+              A list of kernel capabilities to be available for container (this overrides the default set).
652
+
653
+              Conflicts with options 'CapAdd' and 'CapDrop'"
654
+            items:
655
+              type: "string"
648 656
           CapAdd:
649 657
             type: "array"
650
-            description: "A list of kernel capabilities to add to the container."
658
+            description: "A list of kernel capabilities to add to the container. Conflicts with option 'Capabilities'"
651 659
             items:
652 660
               type: "string"
653 661
           CapDrop:
654 662
             type: "array"
655
-            description: "A list of kernel capabilities to drop from the container."
663
+            description: "A list of kernel capabilities to drop from the container. Conflicts with option 'Capabilities'"
656 664
             items:
657 665
               type: "string"
658 666
           Dns:
... ...
@@ -370,9 +370,10 @@ type HostConfig struct {
370 370
 	// Applicable to UNIX platforms
371 371
 	CapAdd          strslice.StrSlice // List of kernel capabilities to add to the container
372 372
 	CapDrop         strslice.StrSlice // List of kernel capabilities to remove from the container
373
-	DNS             []string          `json:"Dns"`        // List of DNS server to lookup
374
-	DNSOptions      []string          `json:"DnsOptions"` // List of DNSOption to look for
375
-	DNSSearch       []string          `json:"DnsSearch"`  // List of DNSSearch to look for
373
+	Capabilities    []string          `json:"Capabilities"` // List of kernel capabilities to be available for container (this overrides the default set)
374
+	DNS             []string          `json:"Dns"`          // List of DNS server to lookup
375
+	DNSOptions      []string          `json:"DnsOptions"`   // List of DNSOption to look for
376
+	DNSSearch       []string          `json:"DnsSearch"`    // List of DNSSearch to look for
376 377
 	ExtraHosts      []string          // List of extra hosts
377 378
 	GroupAdd        []string          // List of additional groups that the container process will run as
378 379
 	IpcMode         IpcMode           // IPC namespace to use for the container
... ...
@@ -15,6 +15,7 @@ import (
15 15
 	"github.com/docker/docker/daemon/network"
16 16
 	"github.com/docker/docker/errdefs"
17 17
 	"github.com/docker/docker/image"
18
+	"github.com/docker/docker/oci/caps"
18 19
 	"github.com/docker/docker/opts"
19 20
 	"github.com/docker/docker/pkg/signal"
20 21
 	"github.com/docker/docker/pkg/system"
... ...
@@ -295,12 +296,35 @@ func validateHostConfig(hostConfig *containertypes.HostConfig, platform string)
295 295
 	if err := validateRestartPolicy(hostConfig.RestartPolicy); err != nil {
296 296
 		return err
297 297
 	}
298
+	if err := validateCapabilities(hostConfig); err != nil {
299
+		return err
300
+	}
298 301
 	if !hostConfig.Isolation.IsValid() {
299 302
 		return errors.Errorf("invalid isolation '%s' on %s", hostConfig.Isolation, runtime.GOOS)
300 303
 	}
301 304
 	return nil
302 305
 }
303 306
 
307
+func validateCapabilities(hostConfig *containertypes.HostConfig) error {
308
+	if len(hostConfig.CapAdd) > 0 && hostConfig.Capabilities != nil {
309
+		return errdefs.InvalidParameter(errors.Errorf("conflicting options: Capabilities and CapAdd"))
310
+	}
311
+	if len(hostConfig.CapDrop) > 0 && hostConfig.Capabilities != nil {
312
+		return errdefs.InvalidParameter(errors.Errorf("conflicting options: Capabilities and CapDrop"))
313
+	}
314
+	if _, err := caps.NormalizeLegacyCapabilities(hostConfig.CapAdd); err != nil {
315
+		return errors.Wrap(err, "invalid CapAdd")
316
+	}
317
+	if _, err := caps.NormalizeLegacyCapabilities(hostConfig.CapDrop); err != nil {
318
+		return errors.Wrap(err, "invalid CapDrop")
319
+	}
320
+	if err := caps.ValidateCapabilities(hostConfig.Capabilities); err != nil {
321
+		return errors.Wrap(err, "invalid Capabilities")
322
+	}
323
+	// TODO consider returning warnings if "Privileged" is combined with Capabilities, CapAdd and/or CapDrop
324
+	return nil
325
+}
326
+
304 327
 // validateHealthCheck validates the healthcheck params of Config
305 328
 func validateHealthCheck(healthConfig *containertypes.HealthConfig) error {
306 329
 	if healthConfig == nil {
... ...
@@ -14,6 +14,7 @@ import (
14 14
 	"github.com/docker/docker/container"
15 15
 	daemonconfig "github.com/docker/docker/daemon/config"
16 16
 	"github.com/docker/docker/oci"
17
+	"github.com/docker/docker/oci/caps"
17 18
 	"github.com/docker/docker/pkg/idtools"
18 19
 	"github.com/docker/docker/pkg/mount"
19 20
 	volumemounts "github.com/docker/docker/volume/mounts"
... ...
@@ -762,7 +763,11 @@ func (daemon *Daemon) createSpec(c *container.Container) (retSpec *specs.Spec, e
762 762
 	if err := setNamespaces(daemon, &s, c); err != nil {
763 763
 		return nil, fmt.Errorf("linux spec namespaces: %v", err)
764 764
 	}
765
-	if err := oci.SetCapabilities(&s, c.HostConfig.CapAdd, c.HostConfig.CapDrop, c.HostConfig.Privileged); err != nil {
765
+	capabilities, err := caps.TweakCapabilities(oci.DefaultCapabilities(), c.HostConfig.CapAdd, c.HostConfig.CapDrop, c.HostConfig.Capabilities, c.HostConfig.Privileged)
766
+	if err != nil {
767
+		return nil, fmt.Errorf("linux spec capabilities: %v", err)
768
+	}
769
+	if err := oci.SetCapabilities(&s, capabilities); err != nil {
766 770
 		return nil, fmt.Errorf("linux spec capabilities: %v", err)
767 771
 	}
768 772
 	if err := setSeccomp(daemon, &s, c); err != nil {
... ...
@@ -10,6 +10,7 @@ import (
10 10
 	containertypes "github.com/docker/docker/api/types/container"
11 11
 	"github.com/docker/docker/container"
12 12
 	"github.com/docker/docker/oci"
13
+	"github.com/docker/docker/oci/caps"
13 14
 	"github.com/docker/docker/pkg/sysinfo"
14 15
 	"github.com/docker/docker/pkg/system"
15 16
 	"github.com/opencontainers/runtime-spec/specs-go"
... ...
@@ -368,7 +369,11 @@ func (daemon *Daemon) createSpecLinuxFields(c *container.Container, s *specs.Spe
368 368
 	}
369 369
 	s.Root.Path = "rootfs"
370 370
 	s.Root.Readonly = c.HostConfig.ReadonlyRootfs
371
-	if err := oci.SetCapabilities(s, c.HostConfig.CapAdd, c.HostConfig.CapDrop, c.HostConfig.Privileged); err != nil {
371
+	capabilities, err := caps.TweakCapabilities(oci.DefaultCapabilities(), c.HostConfig.CapAdd, c.HostConfig.CapDrop, c.HostConfig.Capabilities, c.HostConfig.Privileged)
372
+	if err != nil {
373
+		return fmt.Errorf("linux spec capabilities: %v", err)
374
+	}
375
+	if err := oci.SetCapabilities(s, capabilities); err != nil {
372 376
 		return fmt.Errorf("linux spec capabilities: %v", err)
373 377
 	}
374 378
 	devPermissions, err := oci.AppendDevicePermissionsFromCgroupRules(nil, c.HostConfig.DeviceCgroupRules)
... ...
@@ -37,6 +37,9 @@ keywords: "API, Docker, rcli, REST, documentation"
37 37
 * `GET /service/{id}` now  returns `MaxReplicas` as part of the `Placement`.
38 38
 * `POST /service/create` and `POST /services/(id or name)/update` now take the field `MaxReplicas`
39 39
   as part of the service `Placement`, allowing to specify maximum replicas per node for the service.
40
+* `GET /containers` now returns `Capabilities` field as part of the `HostConfig`.
41
+* `GET /containers/{id}` now returns `Capabilities` field as part of the `HostConfig`.
42
+* `POST /containers/create` now takes `Capabilities` field to set exact list kernel capabilities to be available for      container (this overrides the default set).
40 43
 
41 44
 ## V1.39 API changes
42 45
 
... ...
@@ -1377,6 +1377,8 @@ func (s *DockerSuite) TestPostContainersCreateWithStringOrSliceCmd(c *check.C) {
1377 1377
 }
1378 1378
 
1379 1379
 // regression #14318
1380
+// for backward compatibility testing with and without CAP_ prefix
1381
+// and with upper and lowercase
1380 1382
 func (s *DockerSuite) TestPostContainersCreateWithStringOrSliceCapAddDrop(c *check.C) {
1381 1383
 	// Windows doesn't support CapAdd/CapDrop
1382 1384
 	testRequires(c, DaemonIsLinux)
... ...
@@ -1384,7 +1386,7 @@ func (s *DockerSuite) TestPostContainersCreateWithStringOrSliceCapAddDrop(c *che
1384 1384
 		Image   string
1385 1385
 		CapAdd  string
1386 1386
 		CapDrop string
1387
-	}{"busybox", "NET_ADMIN", "SYS_ADMIN"}
1387
+	}{"busybox", "NET_ADMIN", "cap_sys_admin"}
1388 1388
 	res, _, err := request.Post("/containers/create?name=capaddtest0", request.JSONBody(config))
1389 1389
 	c.Assert(err, checker.IsNil)
1390 1390
 	c.Assert(res.StatusCode, checker.Equals, http.StatusCreated)
... ...
@@ -1393,8 +1395,8 @@ func (s *DockerSuite) TestPostContainersCreateWithStringOrSliceCapAddDrop(c *che
1393 1393
 		Image: "busybox",
1394 1394
 	}
1395 1395
 	hostConfig := containertypes.HostConfig{
1396
-		CapAdd:  []string{"NET_ADMIN", "SYS_ADMIN"},
1397
-		CapDrop: []string{"SETGID"},
1396
+		CapAdd:  []string{"net_admin", "SYS_ADMIN"},
1397
+		CapDrop: []string{"SETGID", "CAP_SETPCAP"},
1398 1398
 	}
1399 1399
 
1400 1400
 	cli, err := client.NewClientWithOpts(client.FromEnv)
... ...
@@ -13,6 +13,7 @@ import (
13 13
 	"github.com/docker/docker/api/types/container"
14 14
 	"github.com/docker/docker/api/types/network"
15 15
 	"github.com/docker/docker/api/types/versions"
16
+	"github.com/docker/docker/client"
16 17
 	ctr "github.com/docker/docker/integration/internal/container"
17 18
 	"github.com/docker/docker/internal/test/request"
18 19
 	"github.com/docker/docker/oci"
... ...
@@ -225,6 +226,131 @@ func TestCreateWithCustomMaskedPaths(t *testing.T) {
225 225
 	}
226 226
 }
227 227
 
228
+func TestCreateWithCapabilities(t *testing.T) {
229
+	skip.If(t, testEnv.DaemonInfo.OSType == "windows", "FIXME: test should be able to run on LCOW")
230
+	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.40"), "Capabilities was added in API v1.40")
231
+
232
+	defer setupTest(t)()
233
+	ctx := context.Background()
234
+	clientNew := request.NewAPIClient(t)
235
+	clientOld := request.NewAPIClient(t, client.WithVersion("1.39"))
236
+
237
+	testCases := []struct {
238
+		doc           string
239
+		hostConfig    container.HostConfig
240
+		expected      []string
241
+		expectedError string
242
+		oldClient     bool
243
+	}{
244
+		{
245
+			doc:        "no capabilities",
246
+			hostConfig: container.HostConfig{},
247
+		},
248
+		{
249
+			doc: "empty capabilities",
250
+			hostConfig: container.HostConfig{
251
+				Capabilities: []string{},
252
+			},
253
+			expected: []string{},
254
+		},
255
+		{
256
+			doc: "valid capabilities",
257
+			hostConfig: container.HostConfig{
258
+				Capabilities: []string{"CAP_NET_RAW", "CAP_SYS_CHROOT"},
259
+			},
260
+			expected: []string{"CAP_NET_RAW", "CAP_SYS_CHROOT"},
261
+		},
262
+		{
263
+			doc: "invalid capabilities",
264
+			hostConfig: container.HostConfig{
265
+				Capabilities: []string{"NET_RAW"},
266
+			},
267
+			expectedError: `invalid Capabilities: unknown capability: "NET_RAW"`,
268
+		},
269
+		{
270
+			doc: "duplicate capabilities",
271
+			hostConfig: container.HostConfig{
272
+				Capabilities: []string{"CAP_SYS_NICE", "CAP_SYS_NICE"},
273
+			},
274
+			expected: []string{"CAP_SYS_NICE", "CAP_SYS_NICE"},
275
+		},
276
+		{
277
+			doc: "capabilities API v1.39",
278
+			hostConfig: container.HostConfig{
279
+				Capabilities: []string{"CAP_NET_RAW", "CAP_SYS_CHROOT"},
280
+			},
281
+			expected:  nil,
282
+			oldClient: true,
283
+		},
284
+		{
285
+			doc: "empty capadd",
286
+			hostConfig: container.HostConfig{
287
+				Capabilities: []string{"CAP_NET_ADMIN"},
288
+				CapAdd:       []string{},
289
+			},
290
+			expected: []string{"CAP_NET_ADMIN"},
291
+		},
292
+		{
293
+			doc: "empty capdrop",
294
+			hostConfig: container.HostConfig{
295
+				Capabilities: []string{"CAP_NET_ADMIN"},
296
+				CapDrop:      []string{},
297
+			},
298
+			expected: []string{"CAP_NET_ADMIN"},
299
+		},
300
+		{
301
+			doc: "capadd capdrop",
302
+			hostConfig: container.HostConfig{
303
+				CapAdd:  []string{"SYS_NICE", "CAP_SYS_NICE"},
304
+				CapDrop: []string{"SYS_NICE", "CAP_SYS_NICE"},
305
+			},
306
+		},
307
+		{
308
+			doc: "conflict with capadd",
309
+			hostConfig: container.HostConfig{
310
+				Capabilities: []string{"CAP_NET_ADMIN"},
311
+				CapAdd:       []string{"SYS_NICE"},
312
+			},
313
+			expectedError: `conflicting options: Capabilities and CapAdd`,
314
+		},
315
+		{
316
+			doc: "conflict with capdrop",
317
+			hostConfig: container.HostConfig{
318
+				Capabilities: []string{"CAP_NET_ADMIN"},
319
+				CapDrop:      []string{"NET_RAW"},
320
+			},
321
+			expectedError: `conflicting options: Capabilities and CapDrop`,
322
+		},
323
+	}
324
+
325
+	for _, tc := range testCases {
326
+		tc := tc
327
+		t.Run(tc.doc, func(t *testing.T) {
328
+			t.Parallel()
329
+			client := clientNew
330
+			if tc.oldClient {
331
+				client = clientOld
332
+			}
333
+
334
+			c, err := client.ContainerCreate(context.Background(),
335
+				&container.Config{Image: "busybox"},
336
+				&tc.hostConfig,
337
+				&network.NetworkingConfig{},
338
+				"",
339
+			)
340
+			if tc.expectedError == "" {
341
+				assert.NilError(t, err)
342
+				ci, err := client.ContainerInspect(ctx, c.ID)
343
+				assert.NilError(t, err)
344
+				assert.Check(t, ci.HostConfig != nil)
345
+				assert.DeepEqual(t, tc.expected, ci.HostConfig.Capabilities)
346
+			} else {
347
+				assert.ErrorContains(t, err, tc.expectedError)
348
+			}
349
+		})
350
+	}
351
+}
352
+
228 353
 func TestCreateWithCustomReadonlyPaths(t *testing.T) {
229 354
 	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
230 355
 
... ...
@@ -4,6 +4,7 @@ import (
4 4
 	"fmt"
5 5
 	"strings"
6 6
 
7
+	"github.com/docker/docker/errdefs"
7 8
 	"github.com/syndtr/gocapability/capability"
8 9
 )
9 10
 
... ...
@@ -67,73 +68,102 @@ func GetAllCapabilities() []string {
67 67
 }
68 68
 
69 69
 // inSlice tests whether a string is contained in a slice of strings or not.
70
-// Comparison is case insensitive
71 70
 func inSlice(slice []string, s string) bool {
72 71
 	for _, ss := range slice {
73
-		if strings.ToLower(s) == strings.ToLower(ss) {
72
+		if s == ss {
74 73
 			return true
75 74
 		}
76 75
 	}
77 76
 	return false
78 77
 }
79 78
 
80
-// TweakCapabilities can tweak capabilities by adding or dropping capabilities
81
-// based on the basics capabilities.
82
-func TweakCapabilities(basics, adds, drops []string) ([]string, error) {
83
-	var (
84
-		newCaps []string
85
-		allCaps = GetAllCapabilities()
86
-	)
79
+const allCapabilities = "ALL"
87 80
 
88
-	// FIXME(tonistiigi): docker format is without CAP_ prefix, oci is with prefix
89
-	// Currently they are mixed in here. We should do conversion in one place.
81
+// NormalizeLegacyCapabilities normalizes, and validates CapAdd/CapDrop capabilities
82
+// by upper-casing them, and adding a CAP_ prefix (if not yet present).
83
+//
84
+// This function also accepts the "ALL" magic-value, that's used by CapAdd/CapDrop.
85
+func NormalizeLegacyCapabilities(caps []string) ([]string, error) {
86
+	var normalized []string
90 87
 
91
-	// look for invalid cap in the drop list
92
-	for _, cap := range drops {
93
-		if strings.ToLower(cap) == "all" {
88
+	valids := GetAllCapabilities()
89
+	for _, c := range caps {
90
+		c = strings.ToUpper(c)
91
+		if c == allCapabilities {
92
+			normalized = append(normalized, c)
94 93
 			continue
95 94
 		}
96
-
97
-		if !inSlice(allCaps, "CAP_"+cap) {
98
-			return nil, fmt.Errorf("Unknown capability drop: %q", cap)
95
+		if !strings.HasPrefix(c, "CAP_") {
96
+			c = "CAP_" + c
97
+		}
98
+		if !inSlice(valids, c) {
99
+			return nil, errdefs.InvalidParameter(fmt.Errorf("unknown capability: %q", c))
99 100
 		}
101
+		normalized = append(normalized, c)
100 102
 	}
103
+	return normalized, nil
104
+}
101 105
 
102
-	// handle --cap-add=all
103
-	if inSlice(adds, "all") {
104
-		basics = allCaps
106
+// ValidateCapabilities validates if caps only contains valid capabilities
107
+func ValidateCapabilities(caps []string) error {
108
+	valids := GetAllCapabilities()
109
+	for _, c := range caps {
110
+		if !inSlice(valids, c) {
111
+			return errdefs.InvalidParameter(fmt.Errorf("unknown capability: %q", c))
112
+		}
105 113
 	}
114
+	return nil
115
+}
106 116
 
107
-	if !inSlice(drops, "all") {
108
-		for _, cap := range basics {
109
-			// skip `all` already handled above
110
-			if strings.ToLower(cap) == "all" {
111
-				continue
112
-			}
113
-
114
-			// if we don't drop `all`, add back all the non-dropped caps
115
-			if !inSlice(drops, cap[4:]) {
116
-				newCaps = append(newCaps, strings.ToUpper(cap))
117
-			}
117
+// TweakCapabilities tweaks capabilities by adding, dropping, or overriding
118
+// capabilities in the basics capabilities list.
119
+func TweakCapabilities(basics, adds, drops, capabilities []string, privileged bool) ([]string, error) {
120
+	switch {
121
+	case privileged:
122
+		// Privileged containers get all capabilities
123
+		return GetAllCapabilities(), nil
124
+	case capabilities != nil:
125
+		// Use custom set of capabilities
126
+		if err := ValidateCapabilities(capabilities); err != nil {
127
+			return nil, err
118 128
 		}
129
+		return capabilities, nil
130
+	case len(adds) == 0 && len(drops) == 0:
131
+		// Nothing to tweak; we're done
132
+		return basics, nil
119 133
 	}
120 134
 
121
-	for _, cap := range adds {
122
-		// skip `all` already handled above
123
-		if strings.ToLower(cap) == "all" {
124
-			continue
125
-		}
135
+	capDrop, err := NormalizeLegacyCapabilities(drops)
136
+	if err != nil {
137
+		return nil, err
138
+	}
139
+	capAdd, err := NormalizeLegacyCapabilities(adds)
140
+	if err != nil {
141
+		return nil, err
142
+	}
126 143
 
127
-		cap = "CAP_" + cap
144
+	var caps []string
128 145
 
129
-		if !inSlice(allCaps, cap) {
130
-			return nil, fmt.Errorf("Unknown capability to add: %q", cap)
146
+	switch {
147
+	case inSlice(capAdd, allCapabilities):
148
+		// Add all capabilities except ones on capDrop
149
+		for _, c := range GetAllCapabilities() {
150
+			if !inSlice(capDrop, c) {
151
+				caps = append(caps, c)
152
+			}
131 153
 		}
132
-
133
-		// add cap if not already in the list
134
-		if !inSlice(newCaps, cap) {
135
-			newCaps = append(newCaps, strings.ToUpper(cap))
154
+	case inSlice(capDrop, allCapabilities):
155
+		// "Drop" all capabilities; use what's in capAdd instead
156
+		caps = capAdd
157
+	default:
158
+		// First drop some capabilities
159
+		for _, c := range basics {
160
+			if !inSlice(capDrop, c) {
161
+				caps = append(caps, c)
162
+			}
136 163
 		}
164
+		// Then add the list of capabilities from capAdd
165
+		caps = append(caps, capAdd...)
137 166
 	}
138
-	return newCaps, nil
167
+	return caps, nil
139 168
 }
... ...
@@ -11,7 +11,8 @@ func iPtr(i int64) *int64        { return &i }
11 11
 func u32Ptr(i int64) *uint32     { u := uint32(i); return &u }
12 12
 func fmPtr(i int64) *os.FileMode { fm := os.FileMode(i); return &fm }
13 13
 
14
-func defaultCapabilities() []string {
14
+// DefaultCapabilities returns a Linux kernel default capabilities
15
+func DefaultCapabilities() []string {
15 16
 	return []string{
16 17
 		"CAP_CHOWN",
17 18
 		"CAP_DAC_OVERRIDE",
... ...
@@ -59,10 +60,10 @@ func DefaultLinuxSpec() specs.Spec {
59 59
 		Version: specs.Version,
60 60
 		Process: &specs.Process{
61 61
 			Capabilities: &specs.LinuxCapabilities{
62
-				Bounding:    defaultCapabilities(),
63
-				Permitted:   defaultCapabilities(),
64
-				Inheritable: defaultCapabilities(),
65
-				Effective:   defaultCapabilities(),
62
+				Bounding:    DefaultCapabilities(),
63
+				Permitted:   DefaultCapabilities(),
64
+				Inheritable: DefaultCapabilities(),
65
+				Effective:   DefaultCapabilities(),
66 66
 			},
67 67
 		},
68 68
 		Root: &specs.Root{},
... ...
@@ -5,7 +5,6 @@ import (
5 5
 	"regexp"
6 6
 	"strconv"
7 7
 
8
-	"github.com/docker/docker/oci/caps"
9 8
 	specs "github.com/opencontainers/runtime-spec/specs-go"
10 9
 )
11 10
 
... ...
@@ -14,19 +13,7 @@ var deviceCgroupRuleRegex = regexp.MustCompile("^([acb]) ([0-9]+|\\*):([0-9]+|\\
14 14
 
15 15
 // SetCapabilities sets the provided capabilities on the spec
16 16
 // All capabilities are added if privileged is true
17
-func SetCapabilities(s *specs.Spec, add, drop []string, privileged bool) error {
18
-	var (
19
-		caplist []string
20
-		err     error
21
-	)
22
-	if privileged {
23
-		caplist = caps.GetAllCapabilities()
24
-	} else {
25
-		caplist, err = caps.TweakCapabilities(s.Process.Capabilities.Bounding, add, drop)
26
-		if err != nil {
27
-			return err
28
-		}
29
-	}
17
+func SetCapabilities(s *specs.Spec, caplist []string) error {
30 18
 	s.Process.Capabilities.Effective = caplist
31 19
 	s.Process.Capabilities.Bounding = caplist
32 20
 	s.Process.Capabilities.Permitted = caplist