@@ -224,36 +224,6 @@ func mountCmd(cmd configs.Command) error {
224
224
return nil
225
225
}
226
226
227
-
func prepareBindMount(m *configs.Mount, rootfs string, mountFd *int) error {
228
-
source := m.Source
229
-
if mountFd != nil {
230
-
source = "/proc/self/fd/" + strconv.Itoa(*mountFd)
231
-
}
232
-
233
-
stat, err := os.Stat(source)
234
-
if err != nil {
235
-
// error out if the source of a bind mount does not exist as we will be
236
-
// unable to bind anything to it.
237
-
return err
238
-
}
239
-
// ensure that the destination of the bind mount is resolved of symlinks at mount time because
240
-
// any previous mounts can invalidate the next mount's destination.
241
-
// this can happen when a user specifies mounts within other mounts to cause breakouts or other
242
-
// evil stuff to try to escape the container's rootfs.
243
-
var dest string
244
-
if dest, err = securejoin.SecureJoin(rootfs, m.Destination); err != nil {
245
-
return err
246
-
}
247
-
if err := checkProcMount(rootfs, dest, m, source); err != nil {
248
-
return err
249
-
}
250
-
if err := createIfNotExists(dest, stat.IsDir()); err != nil {
251
-
return err
252
-
}
253
-
254
-
return nil
255
-
}
256
-
257
227
func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
258
228
binds, err := getCgroupMounts(m)
259
229
if err != nil {
@@ -282,6 +252,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
282
252
for _, b := range binds {
283
253
if c.cgroupns {
284
254
subsystemPath := filepath.Join(c.root, b.Destination)
255
+
subsystemName := filepath.Base(b.Destination)
285
256
if err := os.MkdirAll(subsystemPath, 0o755); err != nil {
286
257
return err
287
258
}
@@ -292,7 +263,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
292
263
}
293
264
var (
294
265
source = "cgroup"
295
-
data = filepath.Base(subsystemPath)
266
+
data = subsystemName
296
267
)
297
268
if data == "systemd" {
298
269
data = cgroups.CgroupNamePrefix + data
@@ -322,14 +293,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
322
293
}
323
294
324
295
func mountCgroupV2(m *configs.Mount, c *mountConfig) error {
325
-
dest, err := securejoin.SecureJoin(c.root, m.Destination)
326
-
if err != nil {
327
-
return err
328
-
}
329
-
if err := os.MkdirAll(dest, 0o755); err != nil {
330
-
return err
331
-
}
332
-
err = utils.WithProcfd(c.root, m.Destination, func(procfd string) error {
296
+
err := utils.WithProcfd(c.root, m.Destination, func(procfd string) error {
333
297
return mount(m.Source, m.Destination, procfd, "cgroup2", uintptr(m.Flags), m.Data)
334
298
})
335
299
if err == nil || !(errors.Is(err, unix.EPERM) || errors.Is(err, unix.EBUSY)) {
@@ -411,6 +375,70 @@ func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) {
411
375
})
412
376
}
413
377
378
+
var errRootfsToFile = errors.New("config tries to change rootfs to file")
379
+
380
+
func createMountpoint(rootfs string, m *configs.Mount, mountFd *int, source string) (string, error) {
381
+
dest, err := securejoin.SecureJoin(rootfs, m.Destination)
382
+
if err != nil {
383
+
return "", err
384
+
}
385
+
if err := checkProcMount(rootfs, dest, m, source); err != nil {
386
+
return "", fmt.Errorf("check proc-safety of %s mount: %w", m.Destination, err)
387
+
}
388
+
389
+
switch m.Device {
390
+
case "bind":
391
+
source := m.Source
392
+
if mountFd != nil {
393
+
source = "/proc/self/fd/" + strconv.Itoa(*mountFd)
394
+
}
395
+
396
+
fi, err := os.Stat(source)
397
+
if err != nil {
398
+
// Error out if the source of a bind mount does not exist as we
399
+
// will be unable to bind anything to it.
400
+
return "", fmt.Errorf("bind mount source stat: %w", err)
401
+
}
402
+
// If the original source is not a directory, make the target a file.
403
+
if !fi.IsDir() {
404
+
// Make sure we aren't tricked into trying to make the root a file.
405
+
if rootfs == dest {
406
+
return "", fmt.Errorf("%w: file bind mount over rootfs", errRootfsToFile)
407
+
}
408
+
// Make the parent directory.
409
+
if err := os.MkdirAll(filepath.Dir(dest), 0o755); err != nil {
410
+
return "", fmt.Errorf("make parent dir of file bind-mount: %w", err)
411
+
}
412
+
// Make the target file.
413
+
f, err := os.OpenFile(dest, os.O_CREATE, 0o755)
414
+
if err != nil {
415
+
return "", fmt.Errorf("create target of file bind-mount: %w", err)
416
+
}
417
+
_ = f.Close()
418
+
// Nothing left to do.
419
+
return dest, nil
420
+
}
421
+
422
+
case "tmpfs":
423
+
// If the original target exists, copy the mode for the tmpfs mount.
424
+
if stat, err := os.Stat(dest); err == nil {
425
+
dt := fmt.Sprintf("mode=%04o", syscallMode(stat.Mode()))
426
+
if m.Data != "" {
427
+
dt = dt + "," + m.Data
428
+
}
429
+
m.Data = dt
430
+
431
+
// Nothing left to do.
432
+
return dest, nil
433
+
}
434
+
}
435
+
436
+
if err := os.MkdirAll(dest, 0o755); err != nil {
437
+
return "", err
438
+
}
439
+
return dest, nil
440
+
}
441
+
414
442
func mountToRootfs(m *configs.Mount, c *mountConfig) error {
415
443
rootfs := c.root
416
444
@@ -442,46 +470,27 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
442
470
return mountPropagate(m, rootfs, "", nil)
443
471
}
444
472
445
-
mountLabel := c.label
446
473
mountFd := c.fd
447
-
dest, err := securejoin.SecureJoin(rootfs, m.Destination)
474
+
dest, err := createMountpoint(rootfs, m, mountFd, m.Source)
448
475
if err != nil {
449
-
return err
476
+
return fmt.Errorf("create mount destination for %s mount: %w", m.Destination, err)
450
477
}
478
+
mountLabel := c.label
451
479
452
480
switch m.Device {
453
481
case "mqueue":
454
-
if err := os.MkdirAll(dest, 0o755); err != nil {
455
-
return err
456
-
}
457
482
if err := mountPropagate(m, rootfs, "", nil); err != nil {
458
483
return err
459
484
}
460
485
return label.SetFileLabel(dest, mountLabel)
461
486
case "tmpfs":
462
-
if stat, err := os.Stat(dest); err != nil {
463
-
if err := os.MkdirAll(dest, 0o755); err != nil {
464
-
return err
465
-
}
466
-
} else {
467
-
dt := fmt.Sprintf("mode=%04o", syscallMode(stat.Mode()))
468
-
if m.Data != "" {
469
-
dt = dt + "," + m.Data
470
-
}
471
-
m.Data = dt
472
-
}
473
-
474
487
if m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP {
475
488
err = doTmpfsCopyUp(m, rootfs, mountLabel)
476
489
} else {
477
490
err = mountPropagate(m, rootfs, mountLabel, nil)
478
491
}
479
-
480
492
return err
481
493
case "bind":
482
-
if err := prepareBindMount(m, rootfs, mountFd); err != nil {
483
-
return err
484
-
}
485
494
if err := mountPropagate(m, rootfs, mountLabel, mountFd); err != nil {
486
495
return err
487
496
}
@@ -509,12 +518,6 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
509
518
}
510
519
return mountCgroupV1(m, c)
511
520
default:
512
-
if err := checkProcMount(rootfs, dest, m, m.Source); err != nil {
513
-
return err
514
-
}
515
-
if err := os.MkdirAll(dest, 0o755); err != nil {
516
-
return err
517
-
}
518
521
return mountPropagate(m, rootfs, mountLabel, mountFd)
519
522
}
520
523
if err := setRecAttr(m, rootfs); err != nil {
@@ -745,6 +748,9 @@ func createDeviceNode(rootfs string, node *devices.Device, bind bool) error {
745
748
if err != nil {
746
749
return err
747
750
}
751
+
if dest == rootfs {
752
+
return fmt.Errorf("%w: mknod over rootfs", errRootfsToFile)
753
+
}
748
754
if err := os.MkdirAll(filepath.Dir(dest), 0o755); err != nil {
749
755
return err
750
756
}
@@ -1011,26 +1017,6 @@ func chroot() error {
1011
1017
return nil
1012
1018
}
1013
1019
1014
-
// createIfNotExists creates a file or a directory only if it does not already exist.
1015
-
func createIfNotExists(path string, isDir bool) error {
1016
-
if _, err := os.Stat(path); err != nil {
1017
-
if os.IsNotExist(err) {
1018
-
if isDir {
1019
-
return os.MkdirAll(path, 0o755)
1020
-
}
1021
-
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
1022
-
return err
1023
-
}
1024
-
f, err := os.OpenFile(path, os.O_CREATE, 0o755)
1025
-
if err != nil {
1026
-
return err
1027
-
}
1028
-
_ = f.Close()
1029
-
}
1030
-
}
1031
-
return nil
1032
-
}
1033
-
1034
1020
// readonlyPath will make a path read only.
1035
1021
func readonlyPath(path string) error {
1036
1022
if err := mount(path, path, "", "", unix.MS_BIND|unix.MS_REC, ""); err != nil {
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4