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

Code before:
		}
	}

	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)
	}

	if err := adjustRootMountPropagation(uintptr(config.RootPropagation)); err != nil {
		return 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
}

// adjustRootMountPropagation applies mount propagation flags such as MS_SHARED or MS_UNBINDABLE
// to the root mount after the pivot_root or chroot has taken place.
//
// 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.
func adjustRootMountPropagation(rootPropagation uintptr) error {
	var flag uintptr

	switch {
	case rootPropagation&unix.MS_SHARED != 0:
		flag = unix.MS_SHARED
	case rootPropagation&unix.MS_UNBINDABLE != 0:
		flag = unix.MS_UNBINDABLE
	default:

Review comment (suggestion):
Yeah, I think that we can use config.RootPropagation directly, and not use a separate function.

Something like
```go
// Apply root mount propagation flags.
if config.RootPropagation != 0 {
 	if err := mount("", "/", "", uintptr(flag), ""); err != nil { 
 		return fmt.Errorf("unable to apply root propagation flags: %w", err )
 	} 
}
```

Code after:
		}
	}

	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.
func finalizeRootfs(config *configs.Config) (err error) {
	// All tmpfs mounts and /dev were previously mounted as rw
	// by mountPropagate. Remount them read-only as requested.
	for _, m := range config.Mounts {
		if m.Flags&unix.MS_RDONLY != unix.MS_RDONLY {
			continue