Repository: opencontainers/runc
File: libcontainer/rootfs_linux.go (Go)

Code before:

	if s := iConfig.SpecState; s != nil {
		s.Pid = unix.Getpid()
		s.Status = specs.StateCreating
		if err := iConfig.Config.Hooks.Run(configs.CreateContainer, s); err != nil {
			return err
		}
	}

	if config.NoPivotRoot {
		err = msMoveRoot(config.Rootfs)
	} else if config.Namespaces.Contains(configs.NEWNS) {
		err = pivotRoot(config.Rootfs)
	} else {
		err = chroot()
	}
	if err != nil {
		return fmt.Errorf("error jailing process inside rootfs: %w", err)
	}

	// Apply root mount propagation flags.
	// This must be done after pivot_root/chroot because the mount propagation flag is applied
	// to the current root ("/"), and not to the old rootfs before it becomes "/". Applying the
	// flag in prepareRoot would affect the host mount namespace if the container's
	// root mount is shared.
	if config.RootPropagation != 0 {
		if err := mount("", "/", "", uintptr(config.RootPropagation), ""); err != nil {
			return fmt.Errorf("unable to apply root propagation flags: %w", err)
		}
	}

	if setupDev {
		if err := reOpenDevNull(); err != nil {
			return fmt.Errorf("error reopening /dev/null inside container: %w", err)
		}
	}

	if cwd := iConfig.Cwd; cwd != "" {
		// Note that spec.Process.Cwd can contain unclean value like  "../../../../foo/bar...".
		// However, we are safe to call MkDirAll directly because we are in the jail here.
		if err := os.MkdirAll(cwd, 0o755); err != nil {
			return err
		}
	}

	return nil
}

// finalizeRootfs sets anything to ro if necessary. You must call
// prepareRootfs first.
func finalizeRootfs(config *configs.Config) (err error) {

Review comment (suggestion):
I think if we add a `unix.MS_PRIVATE` comparison, it will reduce a mount syscall.
```
if config.RootPropagation != 0 && config.RootPropagation & unix.MS_PRIVATE == 0 {
```

Code after:

	if s := iConfig.SpecState; s != nil {
		s.Pid = unix.Getpid()
		s.Status = specs.StateCreating
		if err := iConfig.Config.Hooks.Run(configs.CreateContainer, s); err != nil {
			return err
		}
	}

	if config.NoPivotRoot {
		err = msMoveRoot(config.Rootfs)
	} else if config.Namespaces.Contains(configs.NEWNS) {
		err = pivotRoot(config.Rootfs)
	} else {
		err = chroot()
	}
	if err != nil {
		return fmt.Errorf("error jailing process inside rootfs: %w", err)
	}

	// Apply root mount propagation flags.
	// This must be done after pivot_root/chroot because the mount propagation flag is applied
	// to the current root ("/"), and not to the old rootfs before it becomes "/". Applying the
	// flag in prepareRoot would affect the host mount namespace if the container's
	// root mount is shared.
	// MS_PRIVATE is skipped as rootfsParentMountPrivate() is already called.
	if config.RootPropagation != 0 && config.RootPropagation&unix.MS_PRIVATE == 0 {
		if err := mount("", "/", "", uintptr(config.RootPropagation), ""); err != nil {
			return fmt.Errorf("unable to apply root propagation flags: %w", err)
		}
	}

	if setupDev {
		if err := reOpenDevNull(); err != nil {
			return fmt.Errorf("error reopening /dev/null inside container: %w", err)
		}
	}

	if cwd := iConfig.Cwd; cwd != "" {
		// Note that spec.Process.Cwd can contain unclean value like  "../../../../foo/bar...".
		// However, we are safe to call MkDirAll directly because we are in the jail here.
		if err := os.MkdirAll(cwd, 0o755); err != nil {
			return err
		}
	}

	return nil
}

// finalizeRootfs sets anything to ro if necessary. You must call
// prepareRootfs first.