Browse code

Lock down docker root dir perms.

Do not use 0701 perms.
0701 dir perms allows anyone to traverse the docker dir.
It happens to allow any user to execute, as an example, suid binaries
from image rootfs dirs because it allows traversal AND critically
container users need to be able to do execute things.

0701 on lower directories also happens to allow any user to modify
things in, for instance, the overlay upper dir which neccessarily
has 0755 permissions.

This changes to use 0710 which allows users in the group to traverse.
In userns mode the UID owner is (real) root and the GID is the remapped
root's GID.

This prevents anyone but the remapped root to traverse our directories
(which is required for userns with runc).

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit ef7237442147441a7cadcda0600be1186d81ac73)
Signed-off-by: Brian Goff <cpuguy83@gmail.com>

Brian Goff authored on 2021/07/03 02:27:45
Showing 11 changed files
... ...
@@ -466,5 +466,5 @@ func (daemon *Daemon) setupContainerMountsRoot(c *container.Container) error {
466 466
 	if err != nil {
467 467
 		return err
468 468
 	}
469
-	return idtools.MkdirAllAndChown(p, 0701, idtools.CurrentIdentity())
469
+	return idtools.MkdirAllAndChown(p, 0710, idtools.Identity{UID: idtools.CurrentIdentity().UID, GID: daemon.IdentityMapping().RootPair().GID})
470 470
 }
... ...
@@ -212,10 +212,11 @@ func (daemon *Daemon) create(opts createOpts) (retC *container.Container, retErr
212 212
 	}
213 213
 	ctr.RWLayer = rwLayer
214 214
 
215
-	if err := idtools.MkdirAndChown(ctr.Root, 0701, idtools.CurrentIdentity()); err != nil {
215
+	current := idtools.CurrentIdentity()
216
+	if err := idtools.MkdirAndChown(ctr.Root, 0710, idtools.Identity{UID: current.UID, GID: daemon.IdentityMapping().RootPair().GID}); err != nil {
216 217
 		return nil, err
217 218
 	}
218
-	if err := idtools.MkdirAndChown(ctr.CheckpointDir(), 0700, idtools.CurrentIdentity()); err != nil {
219
+	if err := idtools.MkdirAndChown(ctr.CheckpointDir(), 0700, current); err != nil {
219 220
 		return nil, err
220 221
 	}
221 222
 
... ...
@@ -861,7 +861,10 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
861 861
 	}
862 862
 
863 863
 	daemonRepo := filepath.Join(config.Root, "containers")
864
-	if err := idtools.MkdirAllAndChown(daemonRepo, 0701, idtools.CurrentIdentity()); err != nil {
864
+	if err := idtools.MkdirAllAndChown(daemonRepo, 0710, idtools.Identity{
865
+		UID: idtools.CurrentIdentity().UID,
866
+		GID: rootIDs.GID,
867
+	}); err != nil {
865 868
 		return nil, err
866 869
 	}
867 870
 
... ...
@@ -1216,21 +1216,21 @@ func setupDaemonRoot(config *config.Config, rootDir string, remappedRoot idtools
1216 1216
 		}
1217 1217
 	}
1218 1218
 
1219
+	id := idtools.Identity{UID: idtools.CurrentIdentity().UID, GID: remappedRoot.GID}
1220
+	// First make sure the current root dir has the correct perms.
1221
+	if err := idtools.MkdirAllAndChown(config.Root, 0710, id); err != nil {
1222
+		return errors.Wrapf(err, "could not create or set daemon root permissions: %s", config.Root)
1223
+	}
1224
+
1219 1225
 	// if user namespaces are enabled we will create a subtree underneath the specified root
1220 1226
 	// with any/all specified remapped root uid/gid options on the daemon creating
1221 1227
 	// a new subdirectory with ownership set to the remapped uid/gid (so as to allow
1222 1228
 	// `chdir()` to work for containers namespaced to that uid/gid)
1223 1229
 	if config.RemappedRoot != "" {
1224
-		id := idtools.CurrentIdentity()
1225
-		// First make sure the current root dir has the correct perms.
1226
-		if err := idtools.MkdirAllAndChown(config.Root, 0701, id); err != nil {
1227
-			return errors.Wrapf(err, "could not create or set daemon root permissions: %s", config.Root)
1228
-		}
1229
-
1230 1230
 		config.Root = filepath.Join(rootDir, fmt.Sprintf("%d.%d", remappedRoot.UID, remappedRoot.GID))
1231 1231
 		logrus.Debugf("Creating user namespaced daemon root: %s", config.Root)
1232 1232
 		// Create the root directory if it doesn't exist
1233
-		if err := idtools.MkdirAllAndChown(config.Root, 0701, id); err != nil {
1233
+		if err := idtools.MkdirAllAndChown(config.Root, 0710, id); err != nil {
1234 1234
 			return fmt.Errorf("Cannot create daemon root: %s: %v", config.Root, err)
1235 1235
 		}
1236 1236
 		// we also need to verify that any pre-existing directories in the path to
... ...
@@ -130,14 +130,23 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
130 130
 	}
131 131
 
132 132
 	currentID := idtools.CurrentIdentity()
133
+	_, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
134
+	if err != nil {
135
+		return nil, err
136
+	}
137
+	dirID := idtools.Identity{
138
+		UID: currentID.UID,
139
+		GID: rootGID,
140
+	}
141
+
133 142
 	// Create the root aufs driver dir
134
-	if err := idtools.MkdirAllAndChown(root, 0701, currentID); err != nil {
143
+	if err := idtools.MkdirAllAndChown(root, 0710, dirID); err != nil {
135 144
 		return nil, err
136 145
 	}
137 146
 
138 147
 	// Populate the dir structure
139 148
 	for _, p := range paths {
140
-		if err := idtools.MkdirAllAndChown(path.Join(root, p), 0701, currentID); err != nil {
149
+		if err := idtools.MkdirAllAndChown(path.Join(root, p), 0710, dirID); err != nil {
141 150
 			return nil, err
142 151
 		}
143 152
 	}
... ...
@@ -70,7 +70,14 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
70 70
 		return nil, graphdriver.ErrPrerequisites
71 71
 	}
72 72
 
73
-	if err := idtools.MkdirAllAndChown(home, 0701, idtools.CurrentIdentity()); err != nil {
73
+	remappedRoot := idtools.NewIDMappingsFromMaps(uidMaps, gidMaps)
74
+	currentID := idtools.CurrentIdentity()
75
+	dirID := idtools.Identity{
76
+		UID: currentID.UID,
77
+		GID: remappedRoot.RootPair().GID,
78
+	}
79
+
80
+	if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil {
74 81
 		return nil, err
75 82
 	}
76 83
 
... ...
@@ -521,7 +528,14 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
521 521
 	if err != nil {
522 522
 		return err
523 523
 	}
524
-	if err := idtools.MkdirAllAndChown(subvolumes, 0701, idtools.CurrentIdentity()); err != nil {
524
+
525
+	currentID := idtools.CurrentIdentity()
526
+	dirID := idtools.Identity{
527
+		UID: currentID.UID,
528
+		GID: rootGID,
529
+	}
530
+
531
+	if err := idtools.MkdirAllAndChown(subvolumes, 0710, dirID); err != nil {
525 532
 		return err
526 533
 	}
527 534
 	if parent == "" {
... ...
@@ -88,7 +88,17 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
88 88
 		return nil, graphdriver.ErrNotSupported
89 89
 	}
90 90
 
91
-	if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 0701, idtools.CurrentIdentity()); err != nil {
91
+	remappedRoot := idtools.NewIDMappingsFromMaps(uidMaps, gidMaps)
92
+	currentID := idtools.CurrentIdentity()
93
+	dirID := idtools.Identity{
94
+		UID: currentID.UID,
95
+		GID: remappedRoot.RootPair().GID,
96
+	}
97
+
98
+	if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil {
99
+		return nil, err
100
+	}
101
+	if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 700, currentID); err != nil {
92 102
 		return nil, err
93 103
 	}
94 104
 
... ...
@@ -173,11 +183,15 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr
173 173
 	}
174 174
 	root := idtools.Identity{UID: rootUID, GID: rootGID}
175 175
 
176
-	currentID := idtools.CurrentIdentity()
177
-	if err := idtools.MkdirAllAndChown(path.Dir(dir), 0701, currentID); err != nil {
176
+	dirID := idtools.Identity{
177
+		UID: rootUID,
178
+		GID: rootGID,
179
+	}
180
+
181
+	if err := idtools.MkdirAllAndChown(path.Dir(dir), 0710, dirID); err != nil {
178 182
 		return err
179 183
 	}
180
-	if err := idtools.MkdirAndChown(dir, 0701, currentID); err != nil {
184
+	if err := idtools.MkdirAndChown(dir, 0710, dirID); err != nil {
181 185
 		return err
182 186
 	}
183 187
 
... ...
@@ -211,7 +225,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr
211 211
 		return nil
212 212
 	}
213 213
 
214
-	if err := idtools.MkdirAndChown(path.Join(dir, workDirName), 0701, currentID); err != nil {
214
+	if err := idtools.MkdirAndChown(path.Join(dir, workDirName), 0710, dirID); err != nil {
215 215
 		return err
216 216
 	}
217 217
 
... ...
@@ -156,11 +156,20 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
156 156
 		logrus.WithField("storage-driver", "overlay").Warn(overlayutils.ErrDTypeNotSupported("overlay", backingFs))
157 157
 	}
158 158
 
159
-	// Create the driver home dir
160
-	if err := idtools.MkdirAllAndChown(home, 0701, idtools.CurrentIdentity()); err != nil {
159
+	currentID := idtools.CurrentIdentity()
160
+	_, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
161
+	if err != nil {
161 162
 		return nil, err
162 163
 	}
164
+	dirID := idtools.Identity{
165
+		UID: currentID.UID,
166
+		GID: rootGID,
167
+	}
163 168
 
169
+	// Create the driver home dir
170
+	if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil {
171
+		return nil, err
172
+	}
164 173
 	d := &Driver{
165 174
 		home:          home,
166 175
 		uidMaps:       uidMaps,
... ...
@@ -262,10 +271,11 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr
262 262
 	root := idtools.Identity{UID: rootUID, GID: rootGID}
263 263
 
264 264
 	currentID := idtools.CurrentIdentity()
265
-	if err := idtools.MkdirAllAndChown(path.Dir(dir), 0701, currentID); err != nil {
266
-		return err
265
+	dirID := idtools.Identity{
266
+		UID: currentID.UID,
267
+		GID: rootGID,
267 268
 	}
268
-	if err := idtools.MkdirAndChown(dir, 0701, currentID); err != nil {
269
+	if err := idtools.MkdirAndChown(dir, 0710, dirID); err != nil {
269 270
 		return err
270 271
 	}
271 272
 
... ...
@@ -165,7 +165,20 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
165 165
 		logger.Warn(overlayutils.ErrDTypeNotSupported("overlay2", backingFs))
166 166
 	}
167 167
 
168
-	if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 0701, idtools.CurrentIdentity()); err != nil {
168
+	_, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
169
+	if err != nil {
170
+		return nil, err
171
+	}
172
+
173
+	cur := idtools.CurrentIdentity()
174
+	dirID := idtools.Identity{
175
+		UID: cur.UID,
176
+		GID: rootGID,
177
+	}
178
+	if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil {
179
+		return nil, err
180
+	}
181
+	if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 0700, cur); err != nil {
169 182
 		return nil, err
170 183
 	}
171 184
 
... ...
@@ -344,12 +357,15 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr
344 344
 		return err
345 345
 	}
346 346
 	root := idtools.Identity{UID: rootUID, GID: rootGID}
347
-	current := idtools.CurrentIdentity()
347
+	dirID := idtools.Identity{
348
+		UID: idtools.CurrentIdentity().UID,
349
+		GID: rootGID,
350
+	}
348 351
 
349
-	if err := idtools.MkdirAllAndChown(path.Dir(dir), 0701, current); err != nil {
352
+	if err := idtools.MkdirAllAndChown(path.Dir(dir), 0710, dirID); err != nil {
350 353
 		return err
351 354
 	}
352
-	if err := idtools.MkdirAndChown(dir, 0701, current); err != nil {
355
+	if err := idtools.MkdirAndChown(dir, 0710, dirID); err != nil {
353 356
 		return err
354 357
 	}
355 358
 
... ...
@@ -37,8 +37,16 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
37 37
 	if err := d.parseOptions(options); err != nil {
38 38
 		return nil, err
39 39
 	}
40
+	_, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
41
+	if err != nil {
42
+		return nil, err
43
+	}
40 44
 
41
-	if err := idtools.MkdirAllAndChown(home, 0701, idtools.CurrentIdentity()); err != nil {
45
+	dirID := idtools.Identity{
46
+		UID: idtools.CurrentIdentity().UID,
47
+		GID: rootGID,
48
+	}
49
+	if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil {
42 50
 		return nil, err
43 51
 	}
44 52
 
... ...
@@ -140,7 +148,12 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
140 140
 func (d *Driver) create(id, parent string, size uint64) error {
141 141
 	dir := d.dir(id)
142 142
 	rootIDs := d.idMapping.RootPair()
143
-	if err := idtools.MkdirAllAndChown(filepath.Dir(dir), 0701, idtools.CurrentIdentity()); err != nil {
143
+
144
+	dirID := idtools.Identity{
145
+		UID: idtools.CurrentIdentity().UID,
146
+		GID: rootIDs.GID,
147
+	}
148
+	if err := idtools.MkdirAllAndChown(filepath.Dir(dir), 0710, dirID); err != nil {
144 149
 		return err
145 150
 	}
146 151
 	if err := idtools.MkdirAndChown(dir, 0755, rootIDs); err != nil {
... ...
@@ -104,7 +104,16 @@ func Init(base string, opt []string, uidMaps, gidMaps []idtools.IDMap) (graphdri
104 104
 		return nil, fmt.Errorf("BUG: zfs get all -t filesystem -rHp '%s' should contain '%s'", options.fsName, options.fsName)
105 105
 	}
106 106
 
107
-	if err := idtools.MkdirAllAndChown(base, 0701, idtools.CurrentIdentity()); err != nil {
107
+	_, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
108
+	if err != nil {
109
+		return nil, err
110
+	}
111
+
112
+	dirID := idtools.Identity{
113
+		UID: idtools.CurrentIdentity().UID,
114
+		GID: rootGID,
115
+	}
116
+	if err := idtools.MkdirAllAndChown(base, 0710, dirID); err != nil {
108 117
 		return nil, fmt.Errorf("Failed to create '%s': %v", base, err)
109 118
 	}
110 119