(root *os.File)
| 537 | } |
| 538 | |
| 539 | func (m *mountEntry) createOpenMountpoint(root *os.File) (Err error) { |
| 540 | rootfs := root.Name() |
| 541 | unsafePath := pathrs.LexicallyStripRoot(rootfs, m.Destination) |
| 542 | dstFile, err := pathrs.OpenInRoot(root, unsafePath, unix.O_PATH) |
| 543 | defer func() { |
| 544 | if dstFile != nil && Err != nil { |
| 545 | _ = dstFile.Close() |
| 546 | } |
| 547 | }() |
| 548 | if err == nil && m.Device == "tmpfs" { |
| 549 | // If the original target exists, copy the mode for the tmpfs mount. |
| 550 | stat, err := dstFile.Stat() |
| 551 | if err != nil { |
| 552 | return fmt.Errorf("check tmpfs source mode: %w", err) |
| 553 | } |
| 554 | dt := fmt.Sprintf("mode=%04o", syscallMode(stat.Mode())) |
| 555 | if m.Data != "" { |
| 556 | dt = dt + "," + m.Data |
| 557 | } |
| 558 | m.Data = dt |
| 559 | } |
| 560 | if err != nil { |
| 561 | if !errors.Is(err, unix.ENOENT) { |
| 562 | return fmt.Errorf("lookup mountpoint target: %w", err) |
| 563 | } |
| 564 | |
| 565 | // If the mountpoint doesn't already exist, we want to create a mountpoint |
| 566 | // that makes sense for the source. For file bind-mounts this is an empty |
| 567 | // file, for everything else it's a directory. |
| 568 | dstIsFile := false |
| 569 | if m.Device == "bind" { |
| 570 | fi, _, err := m.srcStat() |
| 571 | if err != nil { |
| 572 | // Error out if the source of a bind mount does not exist as we |
| 573 | // will be unable to bind anything to it. |
| 574 | return err |
| 575 | } |
| 576 | dstIsFile = !fi.IsDir() |
| 577 | } |
| 578 | if dstIsFile { |
| 579 | dstFile, err = pathrs.CreateInRoot(root, unsafePath, unix.O_CREAT|unix.O_EXCL|unix.O_NOFOLLOW, 0o644) |
| 580 | } else { |
| 581 | dstFile, err = pathrs.MkdirAllInRoot(root, unsafePath, 0o755) |
| 582 | } |
| 583 | if err != nil { |
| 584 | return fmt.Errorf("make mountpoint %q: %w", m.Destination, err) |
| 585 | } |
| 586 | } |
| 587 | |
| 588 | dstFullPath, err := procfs.ProcSelfFdReadlink(dstFile) |
| 589 | if err != nil { |
| 590 | return fmt.Errorf("get mount destination real path: %w", err) |
| 591 | } |
| 592 | if !pathrs.IsLexicallyInRoot(rootfs, dstFullPath) { |
| 593 | return fmt.Errorf("mountpoint %q is outside of rootfs %q", dstFullPath, rootfs) |
| 594 | } |
| 595 | if relPath, err := filepath.Rel(rootfs, dstFullPath); err != nil { |
| 596 | return fmt.Errorf("get relative path of %q: %w", dstFullPath, err) |
no test coverage detected