diff --git a/daemon/daemon_experimental.go b/daemon/daemon_experimental.go index d50a8fb283..9ff05271a1 100644 --- a/daemon/daemon_experimental.go +++ b/daemon/daemon_experimental.go @@ -10,7 +10,6 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/docker/api/types/container" - "github.com/docker/docker/pkg/directory" "github.com/docker/docker/pkg/idtools" ) @@ -48,53 +47,36 @@ func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) } func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error { - // the main docker root needs to be accessible by all users, as user namespace support - // will create subdirectories owned by either a) the real system root (when no remapping - // is setup) or b) the remapped root host ID (when --root=uid:gid is used) - // for "first time" users of user namespaces, we need to migrate the current directory - // contents to the "0.0" (root == root "namespace" daemon root) - nsRoot := "0.0" + config.Root = rootDir + // the docker root metadata directory needs to have execute permissions for all users (o+x) + // so that syscalls executing as non-root, operating on subdirectories of the graph root + // (e.g. mounted layers of a container) can traverse this path. + // The user namespace support will create subdirectories for the remapped root host uid:gid + // pair owned by that same uid:gid pair for proper write access to those needed metadata and + // layer content subtrees. if _, err := os.Stat(rootDir); err == nil { - // root current exists; we need to check for a prior migration - if _, err := os.Stat(filepath.Join(rootDir, nsRoot)); err != nil && os.IsNotExist(err) { - // need to migrate current root to "0.0" subroot - // 1. create non-usernamespaced root as "0.0" - if err := os.Mkdir(filepath.Join(rootDir, nsRoot), 0700); err != nil { - return fmt.Errorf("Cannot create daemon root %q: %v", filepath.Join(rootDir, nsRoot), err) - } - // 2. move current root content to "0.0" new subroot - if err := directory.MoveToSubdir(rootDir, nsRoot); err != nil { - return fmt.Errorf("Cannot migrate current daemon root %q for user namespaces: %v", rootDir, err) - } - // 3. chmod outer root to 755 - if chmodErr := os.Chmod(rootDir, 0755); chmodErr != nil { - return chmodErr - } - } - } else if os.IsNotExist(err) { - // no root exists yet, create it 0755 with root:root ownership - if err := os.MkdirAll(rootDir, 0755); err != nil { + // root current exists; verify the access bits are correct by setting them + if err = os.Chmod(rootDir, 0701); err != nil { return err } - // create the "0.0" subroot (so no future "migration" happens of the root) - if err := os.Mkdir(filepath.Join(rootDir, nsRoot), 0700); err != nil { + } else if os.IsNotExist(err) { + // no root exists yet, create it 0701 with root:root ownership + if err := os.MkdirAll(rootDir, 0701); err != nil { return err } } - // for user namespaces we will create a subtree underneath the specified root + // if user namespaces are enabled we will create a subtree underneath the specified root // with any/all specified remapped root uid/gid options on the daemon creating // a new subdirectory with ownership set to the remapped uid/gid (so as to allow // `chdir()` to work for containers namespaced to that uid/gid) if config.RemappedRoot != "" { - nsRoot = fmt.Sprintf("%d.%d", rootUID, rootGID) - } - config.Root = filepath.Join(rootDir, nsRoot) - logrus.Debugf("Creating actual daemon root: %s", config.Root) - - // Create the root directory if it doesn't exists - if err := idtools.MkdirAllAs(config.Root, 0700, rootUID, rootGID); err != nil { - return fmt.Errorf("Cannot create daemon root: %s: %v", config.Root, err) + config.Root = filepath.Join(rootDir, fmt.Sprintf("%d.%d", rootUID, rootGID)) + logrus.Debugf("Creating user namespaced daemon root: %s", config.Root) + // Create the root directory if it doesn't exists + if err := idtools.MkdirAllAs(config.Root, 0700, rootUID, rootGID); err != nil { + return fmt.Errorf("Cannot create daemon root: %s: %v", config.Root, err) + } } return nil } diff --git a/daemon/graphdriver/aufs/aufs.go b/daemon/graphdriver/aufs/aufs.go index aa24185ff4..26b3cef65c 100644 --- a/daemon/graphdriver/aufs/aufs.go +++ b/daemon/graphdriver/aufs/aufs.go @@ -123,7 +123,7 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap // Create the root aufs driver dir and return // if it already exists // If not populate the dir structure - if err := idtools.MkdirAllAs(root, 0755, rootUID, rootGID); err != nil { + if err := idtools.MkdirAllAs(root, 0700, rootUID, rootGID); err != nil { if os.IsExist(err) { return a, nil } @@ -136,7 +136,7 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap // Populate the dir structure for _, p := range paths { - if err := idtools.MkdirAllAs(path.Join(root, p), 0755, rootUID, rootGID); err != nil { + if err := idtools.MkdirAllAs(path.Join(root, p), 0700, rootUID, rootGID); err != nil { return nil, err } } diff --git a/daemon/graphdriver/overlay/overlay.go b/daemon/graphdriver/overlay/overlay.go index 201d5f65fa..59131bba08 100644 --- a/daemon/graphdriver/overlay/overlay.go +++ b/daemon/graphdriver/overlay/overlay.go @@ -146,7 +146,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap return nil, err } // Create the driver home dir - if err := idtools.MkdirAllAs(home, 0755, rootUID, rootGID); err != nil && !os.IsExist(err) { + if err := idtools.MkdirAllAs(home, 0700, rootUID, rootGID); err != nil && !os.IsExist(err) { return nil, err }