Browse code

Merge pull request #5810 from vmarmol/drop-caps

Change libcontainer to drop all capabilities by default.

Victor Marmol authored on 2014/05/17 03:51:41
Showing 3 changed files
... ...
@@ -26,6 +26,11 @@ func New() *libcontainer.Container {
26 26
 			"NET_ADMIN":      false,
27 27
 			"MKNOD":          true,
28 28
 			"SYSLOG":         false,
29
+			"SETUID":         true,
30
+			"SETGID":         true,
31
+			"CHOWN":          true,
32
+			"NET_RAW":        true,
33
+			"DAC_OVERRIDE":   true,
29 34
 		},
30 35
 		Namespaces: map[string]bool{
31 36
 			"NEWNS":  true,
... ...
@@ -7,32 +7,34 @@ import (
7 7
 	"github.com/syndtr/gocapability/capability"
8 8
 )
9 9
 
10
-// DropCapabilities drops capabilities for the current process based
11
-// on the container's configuration.
10
+const allCapabilityTypes = capability.CAPS | capability.BOUNDS
11
+
12
+// DropCapabilities drops all capabilities for the current process expect those specified in the container configuration.
12 13
 func DropCapabilities(container *libcontainer.Container) error {
13
-	if drop := getCapabilitiesMask(container); len(drop) > 0 {
14
-		c, err := capability.NewPid(os.Getpid())
15
-		if err != nil {
16
-			return err
17
-		}
18
-		c.Unset(capability.CAPS|capability.BOUNDS, drop...)
14
+	c, err := capability.NewPid(os.Getpid())
15
+	if err != nil {
16
+		return err
17
+	}
19 18
 
20
-		if err := c.Apply(capability.CAPS | capability.BOUNDS); err != nil {
21
-			return err
22
-		}
19
+	keep := getEnabledCapabilities(container)
20
+	c.Clear(allCapabilityTypes)
21
+	c.Set(allCapabilityTypes, keep...)
22
+
23
+	if err := c.Apply(allCapabilityTypes); err != nil {
24
+		return err
23 25
 	}
24 26
 	return nil
25 27
 }
26 28
 
27
-// getCapabilitiesMask returns the specific cap mask values for the libcontainer types
28
-func getCapabilitiesMask(container *libcontainer.Container) []capability.Cap {
29
-	drop := []capability.Cap{}
29
+// getCapabilitiesMask returns the capabilities that should not be dropped by the container.
30
+func getEnabledCapabilities(container *libcontainer.Container) []capability.Cap {
31
+	keep := []capability.Cap{}
30 32
 	for key, enabled := range container.CapabilitiesMask {
31
-		if !enabled {
33
+		if enabled {
32 34
 			if c := libcontainer.GetCapability(key); c != nil {
33
-				drop = append(drop, c.Value)
35
+				keep = append(keep, c.Value)
34 36
 			}
35 37
 		}
36 38
 	}
37
-	return drop
39
+	return keep
38 40
 }
... ...
@@ -55,6 +55,11 @@ var (
55 55
 		{Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN},
56 56
 		{Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN},
57 57
 		{Key: "SYSLOG", Value: capability.CAP_SYSLOG},
58
+		{Key: "SETUID", Value: capability.CAP_SETUID},
59
+		{Key: "SETGID", Value: capability.CAP_SETGID},
60
+		{Key: "CHOWN", Value: capability.CAP_CHOWN},
61
+		{Key: "NET_RAW", Value: capability.CAP_NET_RAW},
62
+		{Key: "DAC_OVERRIDE", Value: capability.CAP_DAC_OVERRIDE},
58 63
 	}
59 64
 )
60 65