// setupNewMountNamespace is used to initialize a new mount namespace for an new // container in the rootfs that is specified. // // There is no need to unmount the new mounts because as soon as the mount namespace // is no longer in use, the mounts will be removed automatically func setupNewMountNamespace(rootfs, console string, readonly bool) error { // mount as slave so that the new mounts do not propagate to the host if err := system.Mount("", "/", "", syscall.MS_SLAVE|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mounting / as slave %s", err) } if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mouting %s as bind %s", rootfs, err) } if readonly { if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mounting %s as readonly %s", rootfs, err) } } if err := mountSystem(rootfs); err != nil { return fmt.Errorf("mount system %s", err) } if err := copyDevNodes(rootfs); err != nil { return fmt.Errorf("copy dev nodes %s", err) } // In non-privileged mode, this fails. Discard the error. setupLoopbackDevices(rootfs) if err := setupDev(rootfs); err != nil { return err } if console != "" { if err := setupPtmx(rootfs, console); err != nil { return err } } if err := system.Chdir(rootfs); err != nil { return fmt.Errorf("chdir into %s %s", rootfs, err) } pivotDir, err := ioutil.TempDir(rootfs, ".pivot_root") if err != nil { return fmt.Errorf("can't create pivot_root dir %s", pivotDir, err) } if err := system.Pivotroot(rootfs, pivotDir); err != nil { return fmt.Errorf("pivot_root %s", err) } if err := system.Chdir("/"); err != nil { return fmt.Errorf("chdir / %s", err) } // path to pivot dir now changed, update pivotDir = filepath.Join("/", filepath.Base(pivotDir)) if err := system.Unmount(pivotDir, syscall.MNT_DETACH); err != nil { return fmt.Errorf("unmount pivot_root dir %s", err) } if err := os.Remove(pivotDir); err != nil { return fmt.Errorf("remove pivot_root dir %s", err) } system.Umask(0022) return nil }
// FinalizeNamespace drops the caps, sets the correct user // and working dir, and closes any leaky file descriptors // before execing the command inside the namespace func FinalizeNamespace(container *libcontainer.Container) error { if err := system.CloseFdsFrom(3); err != nil { return fmt.Errorf("close open file descriptors %s", err) } // drop capabilities in bounding set before changing user if err := capabilities.DropBoundingSet(container); err != nil { return fmt.Errorf("drop bounding set %s", err) } // preserve existing capabilities while we change users if err := system.SetKeepCaps(); err != nil { return fmt.Errorf("set keep caps %s", err) } if err := SetupUser(container.User); err != nil { return fmt.Errorf("setup user %s", err) } if err := system.ClearKeepCaps(); err != nil { return fmt.Errorf("clear keep caps %s", err) } // drop all other capabilities if err := capabilities.DropCapabilities(container); err != nil { return fmt.Errorf("drop capabilities %s", err) } if container.WorkingDir != "" { if err := system.Chdir(container.WorkingDir); err != nil { return fmt.Errorf("chdir to %s %s", container.WorkingDir, err) } } return nil }
// setupNewMountNamespace is used to initialize a new mount namespace for an new // container in the rootfs that is specified. // // There is no need to unmount the new mounts because as soon as the mount namespace // is no longer in use, the mounts will be removed automatically func setupNewMountNamespace(rootfs, console string, readonly bool) error { // mount as slave so that the new mounts do not propagate to the host if err := system.Mount("", "/", "", syscall.MS_SLAVE|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mounting / as slave %s", err) } if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mouting %s as bind %s", rootfs, err) } if readonly { if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mounting %s as readonly %s", rootfs, err) } } if err := mountSystem(rootfs); err != nil { return fmt.Errorf("mount system %s", err) } if err := copyDevNodes(rootfs); err != nil { return fmt.Errorf("copy dev nodes %s", err) } // In non-privileged mode, this fails. Discard the error. setupLoopbackDevices(rootfs) if err := setupDev(rootfs); err != nil { return err } if console != "" { if err := setupPtmx(rootfs, console); err != nil { return err } } if err := system.Chdir(rootfs); err != nil { return fmt.Errorf("chdir into %s %s", rootfs, err) } if err := system.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil { return fmt.Errorf("mount move %s into / %s", rootfs, err) } if err := system.Chroot("."); err != nil { return fmt.Errorf("chroot . %s", err) } if err := system.Chdir("/"); err != nil { return fmt.Errorf("chdir / %s", err) } system.Umask(0022) return nil }
func MsMoveRoot(rootfs string) error { if err := system.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil { return fmt.Errorf("mount move %s into / %s", rootfs, err) } if err := system.Chroot("."); err != nil { return fmt.Errorf("chroot . %s", err) } return system.Chdir("/") }
// InitializeMountNamespace setups up the devices, mount points, and filesystems for use inside a // new mount namepsace func InitializeMountNamespace(rootfs, console string, container *libcontainer.Container) error { var ( err error flag = syscall.MS_PRIVATE ) if container.NoPivotRoot { flag = syscall.MS_SLAVE } if err := system.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil { return fmt.Errorf("mounting / with flags %X %s", (flag | syscall.MS_REC), err) } if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mouting %s as bind %s", rootfs, err) } if err := mountSystem(rootfs, container); err != nil { return fmt.Errorf("mount system %s", err) } if err := setupBindmounts(rootfs, container.Mounts); err != nil { return fmt.Errorf("bind mounts %s", err) } if err := nodes.CopyN(rootfs, nodes.DefaultNodes, true); err != nil { return fmt.Errorf("copy dev nodes %s", err) } if err := nodes.CopyN(rootfs, nodes.AdditionalNodes, false); err != nil { return fmt.Errorf("copy additional dev nodes %s", err) } if err := SetupPtmx(rootfs, console, container.Context["mount_label"]); err != nil { return err } if err := setupDevSymlinks(rootfs); err != nil { return fmt.Errorf("dev symlinks %s", err) } if err := system.Chdir(rootfs); err != nil { return fmt.Errorf("chdir into %s %s", rootfs, err) } if container.NoPivotRoot { err = MsMoveRoot(rootfs) } else { err = PivotRoot(rootfs) } if err != nil { return err } if container.ReadonlyFs { if err := SetReadonly(); err != nil { return fmt.Errorf("set readonly %s", err) } } system.Umask(0022) return nil }
// InitializeMountNamespace setups up the devices, mount points, and filesystems for use inside a // new mount namepsace func InitializeMountNamespace(rootfs, console string, container *libcontainer.Container) error { var ( err error flag = syscall.MS_PRIVATE ) if container.NoPivotRoot { flag = syscall.MS_SLAVE } if err := system.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil { return fmt.Errorf("mounting / as slave %s", err) } if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mouting %s as bind %s", rootfs, err) } if err := mountSystem(rootfs, container); err != nil { return fmt.Errorf("mount system %s", err) } if err := setupBindmounts(rootfs, container.Mounts); err != nil { return fmt.Errorf("bind mounts %s", err) } if err := nodes.CopyN(rootfs, nodes.DefaultNodes); err != nil { return fmt.Errorf("copy dev nodes %s", err) } if restrictionPath := container.Context["restriction_path"]; restrictionPath != "" { if err := restrict.Restrict(rootfs, restrictionPath); err != nil { return fmt.Errorf("restrict %s", err) } } if err := SetupPtmx(rootfs, console, container.Context["mount_label"]); err != nil { return err } if err := system.Chdir(rootfs); err != nil { return fmt.Errorf("chdir into %s %s", rootfs, err) } if container.NoPivotRoot { err = MsMoveRoot(rootfs) } else { err = PivotRoot(rootfs) } if err != nil { return err } if container.ReadonlyFs { if err := SetReadonly(); err != nil { return fmt.Errorf("set readonly %s", err) } } system.Umask(0022) return nil }
// InitializeMountNamespace sets up the devices, mount points, and filesystems for use inside a // new mount namespace. func InitializeMountNamespace(rootfs, console string, mountConfig *MountConfig) error { var ( err error flag = syscall.MS_PRIVATE ) if mountConfig.NoPivotRoot { flag = syscall.MS_SLAVE } if err := system.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil { return fmt.Errorf("mounting / with flags %X %s", (flag | syscall.MS_REC), err) } if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mouting %s as bind %s", rootfs, err) } if err := mountSystem(rootfs, mountConfig); err != nil { return fmt.Errorf("mount system %s", err) } if err := setupBindmounts(rootfs, mountConfig); err != nil { return fmt.Errorf("bind mounts %s", err) } if err := nodes.CreateDeviceNodes(rootfs, mountConfig.DeviceNodes); err != nil { return fmt.Errorf("create device nodes %s", err) } if err := SetupPtmx(rootfs, console, mountConfig.MountLabel); err != nil { return err } if err := setupDevSymlinks(rootfs); err != nil { return fmt.Errorf("dev symlinks %s", err) } if err := system.Chdir(rootfs); err != nil { return fmt.Errorf("chdir into %s %s", rootfs, err) } if mountConfig.NoPivotRoot { err = MsMoveRoot(rootfs) } else { err = PivotRoot(rootfs) } if err != nil { return err } if mountConfig.ReadonlyFs { if err := SetReadonly(); err != nil { return fmt.Errorf("set readonly %s", err) } } system.Umask(0022) return nil }
// finalizeNamespace drops the caps and sets the correct user // and working dir before execing the command inside the namespace func finalizeNamespace(container *libcontainer.Container) error { if err := capabilities.DropCapabilities(container); err != nil { return fmt.Errorf("drop capabilities %s", err) } if err := setupUser(container); err != nil { return fmt.Errorf("setup user %s", err) } if container.WorkingDir != "" { if err := system.Chdir(container.WorkingDir); err != nil { return fmt.Errorf("chdir to %s %s", container.WorkingDir, err) } } return nil }
// setupNewMountNamespace is used to initialize a new mount namespace for an new // container in the rootfs that is specified. // // There is no need to unmount the new mounts because as soon as the mount namespace // is no longer in use, the mounts will be removed automatically func setupNewMountNamespace(rootfs, console string, readonly, noPivotRoot bool) error { flag := syscall.MS_PRIVATE if noPivotRoot { flag = syscall.MS_SLAVE } if err := system.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil { return fmt.Errorf("mounting / as slave %s", err) } if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mouting %s as bind %s", rootfs, err) } if readonly { if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mounting %s as readonly %s", rootfs, err) } } if err := mountSystem(rootfs); err != nil { return fmt.Errorf("mount system %s", err) } if err := copyDevNodes(rootfs); err != nil { return fmt.Errorf("copy dev nodes %s", err) } // In non-privileged mode, this fails. Discard the error. setupLoopbackDevices(rootfs) if err := setupDev(rootfs); err != nil { return err } if console != "" { if err := setupPtmx(rootfs, console); err != nil { return err } } if err := system.Chdir(rootfs); err != nil { return fmt.Errorf("chdir into %s %s", rootfs, err) } if noPivotRoot { if err := rootMsMove(rootfs); err != nil { return err } } else { if err := rootPivot(rootfs); err != nil { return err } } system.Umask(0022) return nil }
// FinalizeNamespace drops the caps, sets the correct user // and working dir, and closes any leaky file descriptors // before execing the command inside the namespace func FinalizeNamespace(container *libcontainer.Container) error { if err := capabilities.DropCapabilities(container); err != nil { return fmt.Errorf("drop capabilities %s", err) } if err := system.CloseFdsFrom(3); err != nil { return fmt.Errorf("close open file descriptors %s", err) } if err := SetupUser(container.User); err != nil { return fmt.Errorf("setup user %s", err) } if container.WorkingDir != "" { if err := system.Chdir(container.WorkingDir); err != nil { return fmt.Errorf("chdir to %s %s", container.WorkingDir, err) } } return nil }
func PivotRoot(rootfs string) error { pivotDir, err := ioutil.TempDir(rootfs, ".pivot_root") if err != nil { return fmt.Errorf("can't create pivot_root dir %s", pivotDir, err) } if err := system.Pivotroot(rootfs, pivotDir); err != nil { return fmt.Errorf("pivot_root %s", err) } if err := system.Chdir("/"); err != nil { return fmt.Errorf("chdir / %s", err) } // path to pivot dir now changed, update pivotDir = filepath.Join("/", filepath.Base(pivotDir)) if err := system.Unmount(pivotDir, syscall.MNT_DETACH); err != nil { return fmt.Errorf("unmount pivot_root dir %s", err) } return os.Remove(pivotDir) }
// FinalizeNamespace drops the caps, sets the correct user // and working dir, and closes any leaky file descriptors // before execing the command inside the namespace func FinalizeNamespace(container *libcontainer.Config) error { // Ensure that all non-standard fds we may have accidentally // inherited are marked close-on-exec so they stay out of the // container if err := utils.CloseExecFrom(3); err != nil { return fmt.Errorf("close open file descriptors %s", err) } // drop capabilities in bounding set before changing user if err := capabilities.DropBoundingSet(container.Capabilities); err != nil { return fmt.Errorf("drop bounding set %s", err) } // preserve existing capabilities while we change users if err := system.SetKeepCaps(); err != nil { return fmt.Errorf("set keep caps %s", err) } if err := SetupUser(container.User); err != nil { return fmt.Errorf("setup user %s", err) } if err := system.ClearKeepCaps(); err != nil { return fmt.Errorf("clear keep caps %s", err) } // drop all other capabilities if err := capabilities.DropCapabilities(container.Capabilities); err != nil { return fmt.Errorf("drop capabilities %s", err) } if container.WorkingDir != "" { if err := system.Chdir(container.WorkingDir); err != nil { return fmt.Errorf("chdir to %s %s", container.WorkingDir, err) } } return nil }
// setupNewMountNamespace is used to initialize a new mount namespace for an new // container in the rootfs that is specified. // // There is no need to unmount the new mounts because as soon as the mount namespace // is no longer in use, the mounts will be removed automatically func setupNewMountNamespace(rootfs string, bindMounts []libcontainer.Mount, console string, readonly, noPivotRoot bool, mountLabel string) error { flag := syscall.MS_PRIVATE if noPivotRoot { flag = syscall.MS_SLAVE } if err := system.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil { return fmt.Errorf("mounting / as slave %s", err) } if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mouting %s as bind %s", rootfs, err) } if err := mountSystem(rootfs, mountLabel); err != nil { return fmt.Errorf("mount system %s", err) } for _, m := range bindMounts { flags := syscall.MS_BIND | syscall.MS_REC if !m.Writable { flags = flags | syscall.MS_RDONLY } dest := filepath.Join(rootfs, m.Destination) if err := system.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil { return fmt.Errorf("mounting %s into %s %s", m.Source, dest, err) } if m.Private { if err := system.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil { return fmt.Errorf("mounting %s private %s", dest, err) } } } if err := copyDevNodes(rootfs); err != nil { return fmt.Errorf("copy dev nodes %s", err) } // In non-privileged mode, this fails. Discard the error. setupLoopbackDevices(rootfs) if err := setupPtmx(rootfs, console, mountLabel); err != nil { return err } if err := system.Chdir(rootfs); err != nil { return fmt.Errorf("chdir into %s %s", rootfs, err) } if noPivotRoot { if err := rootMsMove(rootfs); err != nil { return err } } else { if err := rootPivot(rootfs); err != nil { return err } } if readonly { if err := system.Mount("/", "/", "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mounting %s as readonly %s", rootfs, err) } } system.Umask(0022) return nil }