LCOW: Create layer folders with correct ACL

Signed-off-by: John Howard <jhoward@microsoft.com>
This commit is contained in:
John Howard 2017-06-01 18:59:11 -07:00
parent f154588226
commit ed10ac6ee9
15 changed files with 49 additions and 42 deletions

View file

@ -126,7 +126,7 @@ func MatchesContentType(contentType, expectedType string) bool {
// LoadOrCreateTrustKey attempts to load the libtrust key at the given path, // LoadOrCreateTrustKey attempts to load the libtrust key at the given path,
// otherwise generates a new one // otherwise generates a new one
func LoadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) { func LoadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) {
err := system.MkdirAll(filepath.Dir(trustKeyPath), 0700) err := system.MkdirAll(filepath.Dir(trustKeyPath), 0700, "")
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -43,7 +43,7 @@ func (container *Container) CreateSecretSymlinks() error {
if err != nil { if err != nil {
return err return err
} }
if err := system.MkdirAll(filepath.Dir(resolvedPath), 0); err != nil { if err := system.MkdirAll(filepath.Dir(resolvedPath), 0, ""); err != nil {
return err return err
} }
if err := os.Symlink(filepath.Join(containerInternalSecretMountPath, r.SecretID), resolvedPath); err != nil { if err := os.Symlink(filepath.Join(containerInternalSecretMountPath, r.SecretID), resolvedPath); err != nil {
@ -85,7 +85,7 @@ func (container *Container) CreateConfigSymlinks() error {
if err != nil { if err != nil {
return err return err
} }
if err := system.MkdirAll(filepath.Dir(resolvedPath), 0); err != nil { if err := system.MkdirAll(filepath.Dir(resolvedPath), 0, ""); err != nil {
return err return err
} }
if err := os.Symlink(filepath.Join(containerInternalConfigsDirPath, configRef.ConfigID), resolvedPath); err != nil { if err := os.Symlink(filepath.Join(containerInternalConfigsDirPath, configRef.ConfigID), resolvedPath); err != nil {

View file

@ -25,7 +25,7 @@ func (daemon *Daemon) setupConfigDir(c *container.Container) (setupErr error) {
logrus.Debugf("configs: setting up config dir: %s", localPath) logrus.Debugf("configs: setting up config dir: %s", localPath)
// create local config root // create local config root
if err := system.MkdirAllWithACL(localPath, 0); err != nil { if err := system.MkdirAllWithACL(localPath, 0, system.SddlAdministratorsLocalSystem); err != nil {
return errors.Wrap(err, "error creating config dir") return errors.Wrap(err, "error creating config dir")
} }
@ -98,7 +98,7 @@ func (daemon *Daemon) setupSecretDir(c *container.Container) (setupErr error) {
logrus.Debugf("secrets: setting up secret dir: %s", localMountPath) logrus.Debugf("secrets: setting up secret dir: %s", localMountPath)
// create local secret root // create local secret root
if err := system.MkdirAllWithACL(localMountPath, 0); err != nil { if err := system.MkdirAllWithACL(localMountPath, 0, system.SddlAdministratorsLocalSystem); err != nil {
return errors.Wrap(err, "error creating secret local directory") return errors.Wrap(err, "error creating secret local directory")
} }

View file

@ -594,7 +594,7 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
} }
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
if err := system.MkdirAll(filepath.Join(config.Root, "credentialspecs"), 0); err != nil && !os.IsExist(err) { if err := system.MkdirAll(filepath.Join(config.Root, "credentialspecs"), 0, ""); err != nil && !os.IsExist(err) {
return nil, err return nil, err
} }
} }
@ -709,7 +709,7 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
trustDir := filepath.Join(config.Root, "trust") trustDir := filepath.Join(config.Root, "trust")
if err := system.MkdirAll(trustDir, 0700); err != nil { if err := system.MkdirAll(trustDir, 0700, ""); err != nil {
return nil, err return nil, err
} }

View file

@ -465,7 +465,7 @@ func setupRemappedRoot(config *config.Config) (*idtools.IDMappings, error) {
func setupDaemonRoot(config *config.Config, rootDir string, rootIDs idtools.IDPair) error { func setupDaemonRoot(config *config.Config, rootDir string, rootIDs idtools.IDPair) error {
config.Root = rootDir config.Root = rootDir
// Create the root directory if it doesn't exists // Create the root directory if it doesn't exists
if err := system.MkdirAllWithACL(config.Root, 0); err != nil && !os.IsExist(err) { if err := system.MkdirAllWithACL(config.Root, 0, system.SddlAdministratorsLocalSystem); err != nil && !os.IsExist(err) {
return err return err
} }
return nil return nil

View file

@ -190,6 +190,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
// Make sure layers are created with the correct ACL so that VMs can access them. // Make sure layers are created with the correct ACL so that VMs can access them.
layerPath := d.dir(id) layerPath := d.dir(id)
logrus.Debugf("lcowdriver: create: id %s: creating layerPath %s", id, layerPath) logrus.Debugf("lcowdriver: create: id %s: creating layerPath %s", id, layerPath)
// Make sure the layers are created with the correct ACL so that VMs can access them.
if err := system.MkdirAllWithACL(layerPath, 755, system.SddlNtvmAdministratorsLocalSystem); err != nil { if err := system.MkdirAllWithACL(layerPath, 755, system.SddlNtvmAdministratorsLocalSystem); err != nil {
return err return err
} }

View file

@ -80,7 +80,7 @@ func New(stateDir string, options ...RemoteOption) (_ Remote, err error) {
} }
} }
if err := system.MkdirAll(stateDir, 0700); err != nil { if err := system.MkdirAll(stateDir, 0700, ""); err != nil {
return nil, err return nil, err
} }

View file

@ -1035,7 +1035,7 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
dst = filepath.Join(dst, filepath.Base(src)) dst = filepath.Join(dst, filepath.Base(src))
} }
// Create the holding directory if necessary // Create the holding directory if necessary
if err := system.MkdirAll(filepath.Dir(dst), 0700); err != nil { if err := system.MkdirAll(filepath.Dir(dst), 0700, ""); err != nil {
return err return err
} }

View file

@ -84,7 +84,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
parentPath := filepath.Join(dest, parent) parentPath := filepath.Join(dest, parent)
if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) { if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
err = system.MkdirAll(parentPath, 0600) err = system.MkdirAll(parentPath, 0600, "")
if err != nil { if err != nil {
return 0, err return 0, err
} }

View file

@ -47,7 +47,7 @@ func TestChrootTarUntar(t *testing.T) {
} }
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
src := filepath.Join(tmpdir, "src") src := filepath.Join(tmpdir, "src")
if err := system.MkdirAll(src, 0700); err != nil { if err := system.MkdirAll(src, 0700, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := ioutil.WriteFile(filepath.Join(src, "toto"), []byte("hello toto"), 0644); err != nil { if err := ioutil.WriteFile(filepath.Join(src, "toto"), []byte("hello toto"), 0644); err != nil {
@ -61,7 +61,7 @@ func TestChrootTarUntar(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
dest := filepath.Join(tmpdir, "src") dest := filepath.Join(tmpdir, "src")
if err := system.MkdirAll(dest, 0700); err != nil { if err := system.MkdirAll(dest, 0700, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := Untar(stream, dest, &archive.TarOptions{ExcludePatterns: []string{"lolo"}}); err != nil { if err := Untar(stream, dest, &archive.TarOptions{ExcludePatterns: []string{"lolo"}}); err != nil {
@ -78,7 +78,7 @@ func TestChrootUntarWithHugeExcludesList(t *testing.T) {
} }
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
src := filepath.Join(tmpdir, "src") src := filepath.Join(tmpdir, "src")
if err := system.MkdirAll(src, 0700); err != nil { if err := system.MkdirAll(src, 0700, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := ioutil.WriteFile(filepath.Join(src, "toto"), []byte("hello toto"), 0644); err != nil { if err := ioutil.WriteFile(filepath.Join(src, "toto"), []byte("hello toto"), 0644); err != nil {
@ -89,7 +89,7 @@ func TestChrootUntarWithHugeExcludesList(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
dest := filepath.Join(tmpdir, "dest") dest := filepath.Join(tmpdir, "dest")
if err := system.MkdirAll(dest, 0700); err != nil { if err := system.MkdirAll(dest, 0700, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
options := &archive.TarOptions{} options := &archive.TarOptions{}
@ -180,7 +180,7 @@ func TestChrootTarUntarWithSymlink(t *testing.T) {
} }
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
src := filepath.Join(tmpdir, "src") src := filepath.Join(tmpdir, "src")
if err := system.MkdirAll(src, 0700); err != nil { if err := system.MkdirAll(src, 0700, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := prepareSourceDirectory(10, src, false); err != nil { if _, err := prepareSourceDirectory(10, src, false); err != nil {
@ -206,7 +206,7 @@ func TestChrootCopyWithTar(t *testing.T) {
} }
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
src := filepath.Join(tmpdir, "src") src := filepath.Join(tmpdir, "src")
if err := system.MkdirAll(src, 0700); err != nil { if err := system.MkdirAll(src, 0700, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := prepareSourceDirectory(10, src, true); err != nil { if _, err := prepareSourceDirectory(10, src, true); err != nil {
@ -252,7 +252,7 @@ func TestChrootCopyFileWithTar(t *testing.T) {
} }
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
src := filepath.Join(tmpdir, "src") src := filepath.Join(tmpdir, "src")
if err := system.MkdirAll(src, 0700); err != nil { if err := system.MkdirAll(src, 0700, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := prepareSourceDirectory(10, src, true); err != nil { if _, err := prepareSourceDirectory(10, src, true); err != nil {
@ -299,7 +299,7 @@ func TestChrootUntarPath(t *testing.T) {
} }
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
src := filepath.Join(tmpdir, "src") src := filepath.Join(tmpdir, "src")
if err := system.MkdirAll(src, 0700); err != nil { if err := system.MkdirAll(src, 0700, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := prepareSourceDirectory(10, src, false); err != nil { if _, err := prepareSourceDirectory(10, src, false); err != nil {
@ -360,7 +360,7 @@ func TestChrootUntarEmptyArchiveFromSlowReader(t *testing.T) {
} }
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
dest := filepath.Join(tmpdir, "dest") dest := filepath.Join(tmpdir, "dest")
if err := system.MkdirAll(dest, 0700); err != nil { if err := system.MkdirAll(dest, 0700, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
stream := &slowEmptyTarReader{size: 10240, chunkSize: 1024} stream := &slowEmptyTarReader{size: 10240, chunkSize: 1024}
@ -376,7 +376,7 @@ func TestChrootApplyEmptyArchiveFromSlowReader(t *testing.T) {
} }
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
dest := filepath.Join(tmpdir, "dest") dest := filepath.Join(tmpdir, "dest")
if err := system.MkdirAll(dest, 0700); err != nil { if err := system.MkdirAll(dest, 0700, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
stream := &slowEmptyTarReader{size: 10240, chunkSize: 1024} stream := &slowEmptyTarReader{size: 10240, chunkSize: 1024}
@ -392,7 +392,7 @@ func TestChrootApplyDotDotFile(t *testing.T) {
} }
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
src := filepath.Join(tmpdir, "src") src := filepath.Join(tmpdir, "src")
if err := system.MkdirAll(src, 0700); err != nil { if err := system.MkdirAll(src, 0700, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := ioutil.WriteFile(filepath.Join(src, "..gitme"), []byte(""), 0644); err != nil { if err := ioutil.WriteFile(filepath.Join(src, "..gitme"), []byte(""), 0644); err != nil {
@ -403,7 +403,7 @@ func TestChrootApplyDotDotFile(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
dest := filepath.Join(tmpdir, "dest") dest := filepath.Join(tmpdir, "dest")
if err := system.MkdirAll(dest, 0700); err != nil { if err := system.MkdirAll(dest, 0700, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := ApplyLayer(dest, stream); err != nil { if _, err := ApplyLayer(dest, stream); err != nil {

View file

@ -49,7 +49,7 @@ func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chown
paths = append(paths, dirPath) paths = append(paths, dirPath)
} }
} }
if err := system.MkdirAll(path, mode); err != nil && !os.IsExist(err) { if err := system.MkdirAll(path, mode, ""); err != nil && !os.IsExist(err) {
return err return err
} }
} else { } else {

View file

@ -11,7 +11,7 @@ import (
// Platforms such as Windows do not support the UID/GID concept. So make this // Platforms such as Windows do not support the UID/GID concept. So make this
// just a wrapper around system.MkdirAll. // just a wrapper around system.MkdirAll.
func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chownExisting bool) error { func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chownExisting bool) error {
if err := system.MkdirAll(path, mode); err != nil && !os.IsExist(err) { if err := system.MkdirAll(path, mode, ""); err != nil && !os.IsExist(err) {
return err return err
} }
return nil return nil

View file

@ -37,7 +37,7 @@ func New(path string) (*PIDFile, error) {
return nil, err return nil, err
} }
// Note MkdirAll returns nil if a directory already exists // Note MkdirAll returns nil if a directory already exists
if err := system.MkdirAll(filepath.Dir(path), os.FileMode(0755)); err != nil { if err := system.MkdirAll(filepath.Dir(path), os.FileMode(0755), ""); err != nil {
return nil, err return nil, err
} }
if err := ioutil.WriteFile(path, []byte(fmt.Sprintf("%d", os.Getpid())), 0644); err != nil { if err := ioutil.WriteFile(path, []byte(fmt.Sprintf("%d", os.Getpid())), 0644); err != nil {

View file

@ -8,15 +8,14 @@ import (
"path/filepath" "path/filepath"
) )
// MkdirAllWithACL is a wrapper for MkdirAll that creates a directory // MkdirAllWithACL is a wrapper for MkdirAll on unix systems.
// ACL'd for Builtin Administrators and Local System. func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
func MkdirAllWithACL(path string, perm os.FileMode) error { return MkdirAll(path, perm, sddl)
return MkdirAll(path, perm)
} }
// MkdirAll creates a directory named path along with any necessary parents, // MkdirAll creates a directory named path along with any necessary parents,
// with permission specified by attribute perm for all dir created. // with permission specified by attribute perm for all dir created.
func MkdirAll(path string, perm os.FileMode) error { func MkdirAll(path string, perm os.FileMode, sddl string) error {
return os.MkdirAll(path, perm) return os.MkdirAll(path, perm)
} }

View file

@ -16,21 +16,28 @@ import (
winio "github.com/Microsoft/go-winio" winio "github.com/Microsoft/go-winio"
) )
const (
// SddlAdministratorsLocalSystem is local administrators plus NT AUTHORITY\System
SddlAdministratorsLocalSystem = "D:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
// SddlNtvmAdministratorsLocalSystem is NT VIRTUAL MACHINE\Virtual Machines plus local administrators plus NT AUTHORITY\System
SddlNtvmAdministratorsLocalSystem = "D:P(A;OICI;GA;;;S-1-5-83-0)(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
)
// MkdirAllWithACL is a wrapper for MkdirAll that creates a directory // MkdirAllWithACL is a wrapper for MkdirAll that creates a directory
// ACL'd for Builtin Administrators and Local System. // with an appropriate SDDL defined ACL.
func MkdirAllWithACL(path string, perm os.FileMode) error { func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
return mkdirall(path, true) return mkdirall(path, true, sddl)
} }
// MkdirAll implementation that is volume path aware for Windows. // MkdirAll implementation that is volume path aware for Windows.
func MkdirAll(path string, _ os.FileMode) error { func MkdirAll(path string, _ os.FileMode, sddl string) error {
return mkdirall(path, false) return mkdirall(path, false, sddl)
} }
// mkdirall is a custom version of os.MkdirAll modified for use on Windows // mkdirall is a custom version of os.MkdirAll modified for use on Windows
// so that it is both volume path aware, and can create a directory with // so that it is both volume path aware, and can create a directory with
// a DACL. // a DACL.
func mkdirall(path string, adminAndLocalSystem bool) error { func mkdirall(path string, applyACL bool, sddl string) error {
if re := regexp.MustCompile(`^\\\\\?\\Volume{[a-z0-9-]+}$`); re.MatchString(path) { if re := regexp.MustCompile(`^\\\\\?\\Volume{[a-z0-9-]+}$`); re.MatchString(path) {
return nil return nil
} }
@ -64,15 +71,15 @@ func mkdirall(path string, adminAndLocalSystem bool) error {
if j > 1 { if j > 1 {
// Create parent // Create parent
err = mkdirall(path[0:j-1], false) err = mkdirall(path[0:j-1], false, sddl)
if err != nil { if err != nil {
return err return err
} }
} }
// Parent now exists; invoke os.Mkdir or mkdirWithACL and use its result. // Parent now exists; invoke os.Mkdir or mkdirWithACL and use its result.
if adminAndLocalSystem { if applyACL {
err = mkdirWithACL(path) err = mkdirWithACL(path, sddl)
} else { } else {
err = os.Mkdir(path, 0) err = os.Mkdir(path, 0)
} }
@ -96,9 +103,9 @@ func mkdirall(path string, adminAndLocalSystem bool) error {
// in golang to cater for creating a directory am ACL permitting full // in golang to cater for creating a directory am ACL permitting full
// access, with inheritance, to any subfolder/file for Built-in Administrators // access, with inheritance, to any subfolder/file for Built-in Administrators
// and Local System. // and Local System.
func mkdirWithACL(name string) error { func mkdirWithACL(name string, sddl string) error {
sa := syscall.SecurityAttributes{Length: 0} sa := syscall.SecurityAttributes{Length: 0}
sddl := "D:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
sd, err := winio.SddlToSecurityDescriptor(sddl) sd, err := winio.SddlToSecurityDescriptor(sddl)
if err != nil { if err != nil {
return &os.PathError{Op: "mkdir", Path: name, Err: err} return &os.PathError{Op: "mkdir", Path: name, Err: err}