Browse code

LCOW: Create layer folders with correct ACL

Signed-off-by: John Howard <jhoward@microsoft.com>

John Howard authored on 2017/06/02 10:59:11
Showing 15 changed files
... ...
@@ -126,7 +126,7 @@ func MatchesContentType(contentType, expectedType string) bool {
126 126
 // LoadOrCreateTrustKey attempts to load the libtrust key at the given path,
127 127
 // otherwise generates a new one
128 128
 func LoadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) {
129
-	err := system.MkdirAll(filepath.Dir(trustKeyPath), 0700)
129
+	err := system.MkdirAll(filepath.Dir(trustKeyPath), 0700, "")
130 130
 	if err != nil {
131 131
 		return nil, err
132 132
 	}
... ...
@@ -43,7 +43,7 @@ func (container *Container) CreateSecretSymlinks() error {
43 43
 		if err != nil {
44 44
 			return err
45 45
 		}
46
-		if err := system.MkdirAll(filepath.Dir(resolvedPath), 0); err != nil {
46
+		if err := system.MkdirAll(filepath.Dir(resolvedPath), 0, ""); err != nil {
47 47
 			return err
48 48
 		}
49 49
 		if err := os.Symlink(filepath.Join(containerInternalSecretMountPath, r.SecretID), resolvedPath); err != nil {
... ...
@@ -85,7 +85,7 @@ func (container *Container) CreateConfigSymlinks() error {
85 85
 		if err != nil {
86 86
 			return err
87 87
 		}
88
-		if err := system.MkdirAll(filepath.Dir(resolvedPath), 0); err != nil {
88
+		if err := system.MkdirAll(filepath.Dir(resolvedPath), 0, ""); err != nil {
89 89
 			return err
90 90
 		}
91 91
 		if err := os.Symlink(filepath.Join(containerInternalConfigsDirPath, configRef.ConfigID), resolvedPath); err != nil {
... ...
@@ -25,7 +25,7 @@ func (daemon *Daemon) setupConfigDir(c *container.Container) (setupErr error) {
25 25
 	logrus.Debugf("configs: setting up config dir: %s", localPath)
26 26
 
27 27
 	// create local config root
28
-	if err := system.MkdirAllWithACL(localPath, 0); err != nil {
28
+	if err := system.MkdirAllWithACL(localPath, 0, system.SddlAdministratorsLocalSystem); err != nil {
29 29
 		return errors.Wrap(err, "error creating config dir")
30 30
 	}
31 31
 
... ...
@@ -98,7 +98,7 @@ func (daemon *Daemon) setupSecretDir(c *container.Container) (setupErr error) {
98 98
 	logrus.Debugf("secrets: setting up secret dir: %s", localMountPath)
99 99
 
100 100
 	// create local secret root
101
-	if err := system.MkdirAllWithACL(localMountPath, 0); err != nil {
101
+	if err := system.MkdirAllWithACL(localMountPath, 0, system.SddlAdministratorsLocalSystem); err != nil {
102 102
 		return errors.Wrap(err, "error creating secret local directory")
103 103
 	}
104 104
 
... ...
@@ -594,7 +594,7 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
594 594
 	}
595 595
 
596 596
 	if runtime.GOOS == "windows" {
597
-		if err := system.MkdirAll(filepath.Join(config.Root, "credentialspecs"), 0); err != nil && !os.IsExist(err) {
597
+		if err := system.MkdirAll(filepath.Join(config.Root, "credentialspecs"), 0, ""); err != nil && !os.IsExist(err) {
598 598
 			return nil, err
599 599
 		}
600 600
 	}
... ...
@@ -709,7 +709,7 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
709 709
 
710 710
 	trustDir := filepath.Join(config.Root, "trust")
711 711
 
712
-	if err := system.MkdirAll(trustDir, 0700); err != nil {
712
+	if err := system.MkdirAll(trustDir, 0700, ""); err != nil {
713 713
 		return nil, err
714 714
 	}
715 715
 
... ...
@@ -465,7 +465,7 @@ func setupRemappedRoot(config *config.Config) (*idtools.IDMappings, error) {
465 465
 func setupDaemonRoot(config *config.Config, rootDir string, rootIDs idtools.IDPair) error {
466 466
 	config.Root = rootDir
467 467
 	// Create the root directory if it doesn't exists
468
-	if err := system.MkdirAllWithACL(config.Root, 0); err != nil && !os.IsExist(err) {
468
+	if err := system.MkdirAllWithACL(config.Root, 0, system.SddlAdministratorsLocalSystem); err != nil && !os.IsExist(err) {
469 469
 		return err
470 470
 	}
471 471
 	return nil
... ...
@@ -190,6 +190,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
190 190
 	// Make sure layers are created with the correct ACL so that VMs can access them.
191 191
 	layerPath := d.dir(id)
192 192
 	logrus.Debugf("lcowdriver: create: id %s: creating layerPath %s", id, layerPath)
193
+	// Make sure the layers are created with the correct ACL so that VMs can access them.
193 194
 	if err := system.MkdirAllWithACL(layerPath, 755, system.SddlNtvmAdministratorsLocalSystem); err != nil {
194 195
 		return err
195 196
 	}
... ...
@@ -80,7 +80,7 @@ func New(stateDir string, options ...RemoteOption) (_ Remote, err error) {
80 80
 		}
81 81
 	}
82 82
 
83
-	if err := system.MkdirAll(stateDir, 0700); err != nil {
83
+	if err := system.MkdirAll(stateDir, 0700, ""); err != nil {
84 84
 		return nil, err
85 85
 	}
86 86
 
... ...
@@ -1035,7 +1035,7 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
1035 1035
 		dst = filepath.Join(dst, filepath.Base(src))
1036 1036
 	}
1037 1037
 	// Create the holding directory if necessary
1038
-	if err := system.MkdirAll(filepath.Dir(dst), 0700); err != nil {
1038
+	if err := system.MkdirAll(filepath.Dir(dst), 0700, ""); err != nil {
1039 1039
 		return err
1040 1040
 	}
1041 1041
 
... ...
@@ -84,7 +84,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
84 84
 			parentPath := filepath.Join(dest, parent)
85 85
 
86 86
 			if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
87
-				err = system.MkdirAll(parentPath, 0600)
87
+				err = system.MkdirAll(parentPath, 0600, "")
88 88
 				if err != nil {
89 89
 					return 0, err
90 90
 				}
... ...
@@ -47,7 +47,7 @@ func TestChrootTarUntar(t *testing.T) {
47 47
 	}
48 48
 	defer os.RemoveAll(tmpdir)
49 49
 	src := filepath.Join(tmpdir, "src")
50
-	if err := system.MkdirAll(src, 0700); err != nil {
50
+	if err := system.MkdirAll(src, 0700, ""); err != nil {
51 51
 		t.Fatal(err)
52 52
 	}
53 53
 	if err := ioutil.WriteFile(filepath.Join(src, "toto"), []byte("hello toto"), 0644); err != nil {
... ...
@@ -61,7 +61,7 @@ func TestChrootTarUntar(t *testing.T) {
61 61
 		t.Fatal(err)
62 62
 	}
63 63
 	dest := filepath.Join(tmpdir, "src")
64
-	if err := system.MkdirAll(dest, 0700); err != nil {
64
+	if err := system.MkdirAll(dest, 0700, ""); err != nil {
65 65
 		t.Fatal(err)
66 66
 	}
67 67
 	if err := Untar(stream, dest, &archive.TarOptions{ExcludePatterns: []string{"lolo"}}); err != nil {
... ...
@@ -78,7 +78,7 @@ func TestChrootUntarWithHugeExcludesList(t *testing.T) {
78 78
 	}
79 79
 	defer os.RemoveAll(tmpdir)
80 80
 	src := filepath.Join(tmpdir, "src")
81
-	if err := system.MkdirAll(src, 0700); err != nil {
81
+	if err := system.MkdirAll(src, 0700, ""); err != nil {
82 82
 		t.Fatal(err)
83 83
 	}
84 84
 	if err := ioutil.WriteFile(filepath.Join(src, "toto"), []byte("hello toto"), 0644); err != nil {
... ...
@@ -89,7 +89,7 @@ func TestChrootUntarWithHugeExcludesList(t *testing.T) {
89 89
 		t.Fatal(err)
90 90
 	}
91 91
 	dest := filepath.Join(tmpdir, "dest")
92
-	if err := system.MkdirAll(dest, 0700); err != nil {
92
+	if err := system.MkdirAll(dest, 0700, ""); err != nil {
93 93
 		t.Fatal(err)
94 94
 	}
95 95
 	options := &archive.TarOptions{}
... ...
@@ -180,7 +180,7 @@ func TestChrootTarUntarWithSymlink(t *testing.T) {
180 180
 	}
181 181
 	defer os.RemoveAll(tmpdir)
182 182
 	src := filepath.Join(tmpdir, "src")
183
-	if err := system.MkdirAll(src, 0700); err != nil {
183
+	if err := system.MkdirAll(src, 0700, ""); err != nil {
184 184
 		t.Fatal(err)
185 185
 	}
186 186
 	if _, err := prepareSourceDirectory(10, src, false); err != nil {
... ...
@@ -206,7 +206,7 @@ func TestChrootCopyWithTar(t *testing.T) {
206 206
 	}
207 207
 	defer os.RemoveAll(tmpdir)
208 208
 	src := filepath.Join(tmpdir, "src")
209
-	if err := system.MkdirAll(src, 0700); err != nil {
209
+	if err := system.MkdirAll(src, 0700, ""); err != nil {
210 210
 		t.Fatal(err)
211 211
 	}
212 212
 	if _, err := prepareSourceDirectory(10, src, true); err != nil {
... ...
@@ -252,7 +252,7 @@ func TestChrootCopyFileWithTar(t *testing.T) {
252 252
 	}
253 253
 	defer os.RemoveAll(tmpdir)
254 254
 	src := filepath.Join(tmpdir, "src")
255
-	if err := system.MkdirAll(src, 0700); err != nil {
255
+	if err := system.MkdirAll(src, 0700, ""); err != nil {
256 256
 		t.Fatal(err)
257 257
 	}
258 258
 	if _, err := prepareSourceDirectory(10, src, true); err != nil {
... ...
@@ -299,7 +299,7 @@ func TestChrootUntarPath(t *testing.T) {
299 299
 	}
300 300
 	defer os.RemoveAll(tmpdir)
301 301
 	src := filepath.Join(tmpdir, "src")
302
-	if err := system.MkdirAll(src, 0700); err != nil {
302
+	if err := system.MkdirAll(src, 0700, ""); err != nil {
303 303
 		t.Fatal(err)
304 304
 	}
305 305
 	if _, err := prepareSourceDirectory(10, src, false); err != nil {
... ...
@@ -360,7 +360,7 @@ func TestChrootUntarEmptyArchiveFromSlowReader(t *testing.T) {
360 360
 	}
361 361
 	defer os.RemoveAll(tmpdir)
362 362
 	dest := filepath.Join(tmpdir, "dest")
363
-	if err := system.MkdirAll(dest, 0700); err != nil {
363
+	if err := system.MkdirAll(dest, 0700, ""); err != nil {
364 364
 		t.Fatal(err)
365 365
 	}
366 366
 	stream := &slowEmptyTarReader{size: 10240, chunkSize: 1024}
... ...
@@ -376,7 +376,7 @@ func TestChrootApplyEmptyArchiveFromSlowReader(t *testing.T) {
376 376
 	}
377 377
 	defer os.RemoveAll(tmpdir)
378 378
 	dest := filepath.Join(tmpdir, "dest")
379
-	if err := system.MkdirAll(dest, 0700); err != nil {
379
+	if err := system.MkdirAll(dest, 0700, ""); err != nil {
380 380
 		t.Fatal(err)
381 381
 	}
382 382
 	stream := &slowEmptyTarReader{size: 10240, chunkSize: 1024}
... ...
@@ -392,7 +392,7 @@ func TestChrootApplyDotDotFile(t *testing.T) {
392 392
 	}
393 393
 	defer os.RemoveAll(tmpdir)
394 394
 	src := filepath.Join(tmpdir, "src")
395
-	if err := system.MkdirAll(src, 0700); err != nil {
395
+	if err := system.MkdirAll(src, 0700, ""); err != nil {
396 396
 		t.Fatal(err)
397 397
 	}
398 398
 	if err := ioutil.WriteFile(filepath.Join(src, "..gitme"), []byte(""), 0644); err != nil {
... ...
@@ -403,7 +403,7 @@ func TestChrootApplyDotDotFile(t *testing.T) {
403 403
 		t.Fatal(err)
404 404
 	}
405 405
 	dest := filepath.Join(tmpdir, "dest")
406
-	if err := system.MkdirAll(dest, 0700); err != nil {
406
+	if err := system.MkdirAll(dest, 0700, ""); err != nil {
407 407
 		t.Fatal(err)
408 408
 	}
409 409
 	if _, err := ApplyLayer(dest, stream); err != nil {
... ...
@@ -49,7 +49,7 @@ func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chown
49 49
 				paths = append(paths, dirPath)
50 50
 			}
51 51
 		}
52
-		if err := system.MkdirAll(path, mode); err != nil && !os.IsExist(err) {
52
+		if err := system.MkdirAll(path, mode, ""); err != nil && !os.IsExist(err) {
53 53
 			return err
54 54
 		}
55 55
 	} else {
... ...
@@ -11,7 +11,7 @@ import (
11 11
 // Platforms such as Windows do not support the UID/GID concept. So make this
12 12
 // just a wrapper around system.MkdirAll.
13 13
 func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chownExisting bool) error {
14
-	if err := system.MkdirAll(path, mode); err != nil && !os.IsExist(err) {
14
+	if err := system.MkdirAll(path, mode, ""); err != nil && !os.IsExist(err) {
15 15
 		return err
16 16
 	}
17 17
 	return nil
... ...
@@ -37,7 +37,7 @@ func New(path string) (*PIDFile, error) {
37 37
 		return nil, err
38 38
 	}
39 39
 	// Note MkdirAll returns nil if a directory already exists
40
-	if err := system.MkdirAll(filepath.Dir(path), os.FileMode(0755)); err != nil {
40
+	if err := system.MkdirAll(filepath.Dir(path), os.FileMode(0755), ""); err != nil {
41 41
 		return nil, err
42 42
 	}
43 43
 	if err := ioutil.WriteFile(path, []byte(fmt.Sprintf("%d", os.Getpid())), 0644); err != nil {
... ...
@@ -8,15 +8,14 @@ import (
8 8
 	"path/filepath"
9 9
 )
10 10
 
11
-// MkdirAllWithACL is a wrapper for MkdirAll that creates a directory
12
-// ACL'd for Builtin Administrators and Local System.
13
-func MkdirAllWithACL(path string, perm os.FileMode) error {
14
-	return MkdirAll(path, perm)
11
+// MkdirAllWithACL is a wrapper for MkdirAll on unix systems.
12
+func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
13
+	return MkdirAll(path, perm, sddl)
15 14
 }
16 15
 
17 16
 // MkdirAll creates a directory named path along with any necessary parents,
18 17
 // with permission specified by attribute perm for all dir created.
19
-func MkdirAll(path string, perm os.FileMode) error {
18
+func MkdirAll(path string, perm os.FileMode, sddl string) error {
20 19
 	return os.MkdirAll(path, perm)
21 20
 }
22 21
 
... ...
@@ -16,21 +16,28 @@ import (
16 16
 	winio "github.com/Microsoft/go-winio"
17 17
 )
18 18
 
19
+const (
20
+	// SddlAdministratorsLocalSystem is local administrators plus NT AUTHORITY\System
21
+	SddlAdministratorsLocalSystem = "D:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
22
+	// SddlNtvmAdministratorsLocalSystem is NT VIRTUAL MACHINE\Virtual Machines plus local administrators plus NT AUTHORITY\System
23
+	SddlNtvmAdministratorsLocalSystem = "D:P(A;OICI;GA;;;S-1-5-83-0)(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
24
+)
25
+
19 26
 // MkdirAllWithACL is a wrapper for MkdirAll that creates a directory
20
-// ACL'd for Builtin Administrators and Local System.
21
-func MkdirAllWithACL(path string, perm os.FileMode) error {
22
-	return mkdirall(path, true)
27
+// with an appropriate SDDL defined ACL.
28
+func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
29
+	return mkdirall(path, true, sddl)
23 30
 }
24 31
 
25 32
 // MkdirAll implementation that is volume path aware for Windows.
26
-func MkdirAll(path string, _ os.FileMode) error {
27
-	return mkdirall(path, false)
33
+func MkdirAll(path string, _ os.FileMode, sddl string) error {
34
+	return mkdirall(path, false, sddl)
28 35
 }
29 36
 
30 37
 // mkdirall is a custom version of os.MkdirAll modified for use on Windows
31 38
 // so that it is both volume path aware, and can create a directory with
32 39
 // a DACL.
33
-func mkdirall(path string, adminAndLocalSystem bool) error {
40
+func mkdirall(path string, applyACL bool, sddl string) error {
34 41
 	if re := regexp.MustCompile(`^\\\\\?\\Volume{[a-z0-9-]+}$`); re.MatchString(path) {
35 42
 		return nil
36 43
 	}
... ...
@@ -64,15 +71,15 @@ func mkdirall(path string, adminAndLocalSystem bool) error {
64 64
 
65 65
 	if j > 1 {
66 66
 		// Create parent
67
-		err = mkdirall(path[0:j-1], false)
67
+		err = mkdirall(path[0:j-1], false, sddl)
68 68
 		if err != nil {
69 69
 			return err
70 70
 		}
71 71
 	}
72 72
 
73 73
 	// Parent now exists; invoke os.Mkdir or mkdirWithACL and use its result.
74
-	if adminAndLocalSystem {
75
-		err = mkdirWithACL(path)
74
+	if applyACL {
75
+		err = mkdirWithACL(path, sddl)
76 76
 	} else {
77 77
 		err = os.Mkdir(path, 0)
78 78
 	}
... ...
@@ -96,9 +103,9 @@ func mkdirall(path string, adminAndLocalSystem bool) error {
96 96
 // in golang to cater for creating a directory am ACL permitting full
97 97
 // access, with inheritance, to any subfolder/file for Built-in Administrators
98 98
 // and Local System.
99
-func mkdirWithACL(name string) error {
99
+func mkdirWithACL(name string, sddl string) error {
100 100
 	sa := syscall.SecurityAttributes{Length: 0}
101
-	sddl := "D:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
101
+
102 102
 	sd, err := winio.SddlToSecurityDescriptor(sddl)
103 103
 	if err != nil {
104 104
 		return &os.PathError{Op: "mkdir", Path: name, Err: err}