Browse code

SETUID/SETGID not required for changing user

It is no longer necessary to pass "SETUID" or "SETGID" capabilities to
the container when a "user" is specified in the config.

Docker-DCO-1.1-Signed-off-by: Bernerd Schaefer <bj.schaefer@gmail.com> (github: bernerdschaefer)

Bernerd Schaefer authored on 2014/05/28 23:41:48
Showing 2 changed files
... ...
@@ -172,15 +172,33 @@ func setupNetwork(container *libcontainer.Container, context libcontainer.Contex
172 172
 // and working dir, and closes any leaky file descriptors
173 173
 // before execing the command inside the namespace
174 174
 func FinalizeNamespace(container *libcontainer.Container) error {
175
-	if err := capabilities.DropCapabilities(container); err != nil {
176
-		return fmt.Errorf("drop capabilities %s", err)
177
-	}
178 175
 	if err := system.CloseFdsFrom(3); err != nil {
179 176
 		return fmt.Errorf("close open file descriptors %s", err)
180 177
 	}
178
+
179
+	// drop capabilities in bounding set before changing user
180
+	if err := capabilities.DropBoundingSet(container); err != nil {
181
+		return fmt.Errorf("drop bounding set %s", err)
182
+	}
183
+
184
+	// preserve existing capabilities while we change users
185
+	if err := system.SetKeepCaps(); err != nil {
186
+		return fmt.Errorf("set keep caps %s", err)
187
+	}
188
+
181 189
 	if err := SetupUser(container.User); err != nil {
182 190
 		return fmt.Errorf("setup user %s", err)
183 191
 	}
192
+
193
+	if err := system.ClearKeepCaps(); err != nil {
194
+		return fmt.Errorf("clear keep caps %s", err)
195
+	}
196
+
197
+	// drop all other capabilities
198
+	if err := capabilities.DropCapabilities(container); err != nil {
199
+		return fmt.Errorf("drop capabilities %s", err)
200
+	}
201
+
184 202
 	if container.WorkingDir != "" {
185 203
 		if err := system.Chdir(container.WorkingDir); err != nil {
186 204
 			return fmt.Errorf("chdir to %s %s", container.WorkingDir, err)
... ...
@@ -9,6 +9,25 @@ import (
9 9
 
10 10
 const allCapabilityTypes = capability.CAPS | capability.BOUNDS
11 11
 
12
+// DropBoundingSet drops the capability bounding set to those specified in the
13
+// container configuration.
14
+func DropBoundingSet(container *libcontainer.Container) error {
15
+	c, err := capability.NewPid(os.Getpid())
16
+	if err != nil {
17
+		return err
18
+	}
19
+
20
+	keep := getEnabledCapabilities(container)
21
+	c.Clear(capability.BOUNDS)
22
+	c.Set(capability.BOUNDS, keep...)
23
+
24
+	if err := c.Apply(capability.BOUNDS); err != nil {
25
+		return err
26
+	}
27
+
28
+	return nil
29
+}
30
+
12 31
 // DropCapabilities drops all capabilities for the current process expect those specified in the container configuration.
13 32
 func DropCapabilities(container *libcontainer.Container) error {
14 33
 	c, err := capability.NewPid(os.Getpid())