Browse code

Make host directory mounts use idtools.MkdirAllNewAs

This makes sure that:
1. Already existing directories are left untouched
2. Newly created directories are chowned to the correct root UID/GID in case of user namespaces
3. All parent directories still get created with host root UID/GID

Fix #21738

Signed-off-by: Antonis Kalipetis <akalipetis@gmail.com>

Antonis Kalipetis authored on 2016/08/23 17:33:38
Showing 2 changed files
... ...
@@ -28,7 +28,8 @@ func (daemon *Daemon) setupMounts(c *container.Container) ([]container.Mount, er
28 28
 		if err := daemon.lazyInitializeVolume(c.ID, m); err != nil {
29 29
 			return nil, err
30 30
 		}
31
-		path, err := m.Setup(c.MountLabel)
31
+		rootUID, rootGID := daemon.GetRemappedUIDGID()
32
+		path, err := m.Setup(c.MountLabel, rootUID, rootGID)
32 33
 		if err != nil {
33 34
 			return nil, err
34 35
 		}
... ...
@@ -6,8 +6,8 @@ import (
6 6
 	"strings"
7 7
 	"syscall"
8 8
 
9
+	"github.com/docker/docker/pkg/idtools"
9 10
 	"github.com/docker/docker/pkg/stringid"
10
-	"github.com/docker/docker/pkg/system"
11 11
 	mounttypes "github.com/docker/engine-api/types/mount"
12 12
 	"github.com/opencontainers/runc/libcontainer/label"
13 13
 )
... ...
@@ -107,7 +107,7 @@ type MountPoint struct {
107 107
 
108 108
 // Setup sets up a mount point by either mounting the volume if it is
109 109
 // configured, or creating the source directory if supplied.
110
-func (m *MountPoint) Setup(mountLabel string) (string, error) {
110
+func (m *MountPoint) Setup(mountLabel string, rootUID, rootGID int) (string, error) {
111 111
 	if m.Volume != nil {
112 112
 		if m.ID == "" {
113 113
 			m.ID = stringid.GenerateNonCryptoID()
... ...
@@ -117,8 +117,9 @@ func (m *MountPoint) Setup(mountLabel string) (string, error) {
117 117
 	if len(m.Source) == 0 {
118 118
 		return "", fmt.Errorf("Unable to setup mount point, neither source nor volume defined")
119 119
 	}
120
-	// system.MkdirAll() produces an error if m.Source exists and is a file (not a directory),
121
-	if err := system.MkdirAll(m.Source, 0755); err != nil {
120
+	// idtools.MkdirAllNewAs() produces an error if m.Source exists and is a file (not a directory)
121
+	// also, makes sure that if the directory is created, the correct remapped rootUID/rootGID will own it
122
+	if err := idtools.MkdirAllNewAs(m.Source, 0755, rootUID, rootGID); err != nil {
122 123
 		if perr, ok := err.(*os.PathError); ok {
123 124
 			if perr.Err != syscall.ENOTDIR {
124 125
 				return "", err