Beispiel #1
0
func (container *Container) networkMounts() []execdriver.Mount {
	var mounts []execdriver.Mount
	if container.ResolvConfPath != "" {
		label.SetFileLabel(container.ResolvConfPath, container.MountLabel)
		mounts = append(mounts, execdriver.Mount{
			Source:      container.ResolvConfPath,
			Destination: "/etc/resolv.conf",
			Writable:    !container.hostConfig.ReadonlyRootfs,
			Private:     true,
		})
	}
	if container.HostnamePath != "" {
		label.SetFileLabel(container.HostnamePath, container.MountLabel)
		mounts = append(mounts, execdriver.Mount{
			Source:      container.HostnamePath,
			Destination: "/etc/hostname",
			Writable:    !container.hostConfig.ReadonlyRootfs,
			Private:     true,
		})
	}
	if container.HostsPath != "" {
		label.SetFileLabel(container.HostsPath, container.MountLabel)
		mounts = append(mounts, execdriver.Mount{
			Source:      container.HostsPath,
			Destination: "/etc/hosts",
			Writable:    !container.hostConfig.ReadonlyRootfs,
			Private:     true,
		})
	}
	return mounts
}
Beispiel #2
0
func (container *Container) setupMounts() error {
	mounts := []execdriver.Mount{
		{Source: container.ResolvConfPath, Destination: "/etc/resolv.conf", Writable: true, Private: true},
	}

	if container.HostnamePath != "" {
		mounts = append(mounts, execdriver.Mount{Source: container.HostnamePath, Destination: "/etc/hostname", Writable: true, Private: true})
	}

	if container.HostsPath != "" {
		mounts = append(mounts, execdriver.Mount{Source: container.HostsPath, Destination: "/etc/hosts", Writable: true, Private: true})
	}

	for _, m := range mounts {
		if err := label.SetFileLabel(m.Source, container.MountLabel); err != nil {
			return err
		}
	}

	// Mount user specified volumes
	// Note, these are not private because you may want propagation of (un)mounts from host
	// volumes. For instance if you use -v /usr:/usr and the host later mounts /usr/share you
	// want this new mount in the container
	// These mounts must be ordered based on the length of the path that it is being mounted to (lexicographic)
	for _, path := range container.sortedVolumeMounts() {
		mounts = append(mounts, execdriver.Mount{
			Source:      container.Volumes[path],
			Destination: path,
			Writable:    container.VolumesRW[path],
		})
	}

	container.command.Mounts = mounts
	return nil
}
Beispiel #3
0
// Setup initializes the proper /dev/console inside the rootfs path
func Setup(rootfs, consolePath, mountLabel string) error {
	oldMask := syscall.Umask(0000)
	defer syscall.Umask(oldMask)

	if err := os.Chmod(consolePath, 0600); err != nil {
		return err
	}

	if err := os.Chown(consolePath, 0, 0); err != nil {
		return err
	}

	if err := label.SetFileLabel(consolePath, mountLabel); err != nil {
		return fmt.Errorf("set file label %s %s", consolePath, err)
	}

	dest := filepath.Join(rootfs, "dev/console")

	f, err := os.Create(dest)
	if err != nil && !os.IsExist(err) {
		return fmt.Errorf("create %s %s", dest, err)
	}

	if f != nil {
		f.Close()
	}

	if err := syscall.Mount(consolePath, dest, "bind", syscall.MS_BIND, ""); err != nil {
		return fmt.Errorf("bind %s to %s %s", consolePath, dest, err)
	}

	return nil
}
Beispiel #4
0
// mount initializes the console inside the rootfs mounting with the specified mount label
// and applying the correct ownership of the console.
func (c *linuxConsole) mount(rootfs, mountLabel string, uid, gid int) error {
	oldMask := syscall.Umask(0000)
	defer syscall.Umask(oldMask)
	if err := label.SetFileLabel(c.slavePath, mountLabel); err != nil {
		return err
	}
	dest := filepath.Join(rootfs, "/dev/console")
	f, err := os.Create(dest)
	if err != nil && !os.IsExist(err) {
		return err
	}
	if f != nil {
		f.Close()
	}
	return syscall.Mount(c.slavePath, dest, "bind", syscall.MS_BIND, "")
}
Beispiel #5
0
func (d *Driver) Create(id, parent string) error {
	dir := d.dir(id)
	if err := system.MkdirAll(filepath.Dir(dir), 0700); err != nil {
		return err
	}
	if err := os.Mkdir(dir, 0755); err != nil {
		return err
	}
	opts := []string{"level:s0"}
	if _, mountLabel, err := label.InitLabels(opts); err == nil {
		label.SetFileLabel(dir, mountLabel)
	}
	if parent == "" {
		return nil
	}
	parentDir, err := d.Get(parent, "")
	if err != nil {
		return fmt.Errorf("%s: %s", parent, err)
	}
	if err := chrootarchive.CopyWithTar(parentDir, dir); err != nil {
		return err
	}
	return nil
}
Beispiel #6
0
func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
	var (
		dest = m.Destination
		data = label.FormatMountLabel(m.Data, mountLabel)
	)
	if !strings.HasPrefix(dest, rootfs) {
		dest = filepath.Join(rootfs, dest)
	}

	switch m.Device {
	case "proc", "sysfs":
		if err := os.MkdirAll(dest, 0755); err != nil && !os.IsExist(err) {
			return err
		}
		return syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), "")
	case "mqueue":
		if err := os.MkdirAll(dest, 0755); err != nil && !os.IsExist(err) {
			return err
		}
		if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), ""); err != nil {
			return err
		}
		return label.SetFileLabel(dest, mountLabel)
	case "tmpfs":
		stat, err := os.Stat(dest)
		if err != nil {
			if err := os.MkdirAll(dest, 0755); err != nil && !os.IsExist(err) {
				return err
			}
		}
		if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), data); err != nil {
			return err
		}
		if stat != nil {
			if err = os.Chmod(dest, stat.Mode()); err != nil {
				return err
			}
		}
		return nil
	case "devpts":
		if err := os.MkdirAll(dest, 0755); err != nil && !os.IsExist(err) {
			return err
		}
		return syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), data)
	case "bind":
		stat, err := os.Stat(m.Source)
		if err != nil {
			// error out if the source of a bind mount does not exist as we will be
			// unable to bind anything to it.
			return err
		}
		// ensure that the destination of the bind mount is resolved of symlinks at mount time because
		// any previous mounts can invalidate the next mount's destination.
		// this can happen when a user specifies mounts within other mounts to cause breakouts or other
		// evil stuff to try to escape the container's rootfs.
		if dest, err = symlink.FollowSymlinkInScope(filepath.Join(rootfs, m.Destination), rootfs); err != nil {
			return err
		}
		if err := checkMountDestination(rootfs, dest); err != nil {
			return err
		}
		if err := createIfNotExists(dest, stat.IsDir()); err != nil {
			return err
		}
		if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), data); err != nil {
			return err
		}
		if m.Flags&syscall.MS_RDONLY != 0 {
			if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags|syscall.MS_REMOUNT), ""); err != nil {
				return err
			}
		}
		if m.Relabel != "" {
			if err := label.Relabel(m.Source, mountLabel, m.Relabel); err != nil {
				return err
			}
		}
		if m.Flags&syscall.MS_PRIVATE != 0 {
			if err := syscall.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil {
				return err
			}
		}
	case "cgroup":
		mounts, err := cgroups.GetCgroupMounts()
		if err != nil {
			return err
		}
		var binds []*configs.Mount
		for _, mm := range mounts {
			dir, err := mm.GetThisCgroupDir()
			if err != nil {
				return err
			}
			binds = append(binds, &configs.Mount{
				Device:      "bind",
				Source:      filepath.Join(mm.Mountpoint, dir),
				Destination: filepath.Join(m.Destination, strings.Join(mm.Subsystems, ",")),
				Flags:       syscall.MS_BIND | syscall.MS_REC | syscall.MS_RDONLY,
			})
		}
		tmpfs := &configs.Mount{
			Device:      "tmpfs",
			Destination: m.Destination,
			Flags:       syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV,
		}
		if err := mountToRootfs(tmpfs, rootfs, mountLabel); err != nil {
			return err
		}
		for _, b := range binds {
			if err := mountToRootfs(b, rootfs, mountLabel); err != nil {
				return err
			}
		}
	default:
		return fmt.Errorf("unknown mount device %q to %q", m.Device, m.Destination)
	}
	return nil
}
Beispiel #7
0
func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
	var (
		dest = m.Destination
		data = label.FormatMountLabel(m.Data, mountLabel)
	)
	if !strings.HasPrefix(dest, rootfs) {
		dest = filepath.Join(rootfs, dest)
	}

	switch m.Device {
	case "proc", "sysfs":
		if err := os.MkdirAll(dest, 0755); err != nil && !os.IsExist(err) {
			return err
		}
		return syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), "")
	case "mqueue":
		if err := os.MkdirAll(dest, 0755); err != nil && !os.IsExist(err) {
			return err
		}
		if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), ""); err != nil {
			return err
		}
		return label.SetFileLabel(dest, mountLabel)
	case "tmpfs":
		stat, err := os.Stat(dest)
		if err != nil {
			if err := os.MkdirAll(dest, 0755); err != nil && !os.IsExist(err) {
				return err
			}
		}
		if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), data); err != nil {
			return err
		}
		if stat != nil {
			if err = os.Chmod(dest, stat.Mode()); err != nil {
				return err
			}
		}
		return nil
	case "devpts":
		if err := os.MkdirAll(dest, 0755); err != nil && !os.IsExist(err) {
			return err
		}
		return syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), data)
	case "bind":
		stat, err := os.Stat(m.Source)
		if err != nil {
			// error out if the source of a bind mount does not exist as we will be
			// unable to bind anything to it.
			return err
		}
		if err := createIfNotExists(dest, stat.IsDir()); err != nil {
			return err
		}
		if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), data); err != nil {
			return err
		}
		if m.Flags&syscall.MS_RDONLY != 0 {
			if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags|syscall.MS_REMOUNT), ""); err != nil {
				return err
			}
		}
		if m.Relabel != "" {
			if err := label.Relabel(m.Source, mountLabel, m.Relabel); err != nil {
				return err
			}
		}
		if m.Flags&syscall.MS_PRIVATE != 0 {
			if err := syscall.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil {
				return err
			}
		}
	default:
		return fmt.Errorf("unknown mount device %q to %q", m.Device, m.Destination)
	}
	return nil
}
Beispiel #8
0
func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
	var (
		dest = m.Destination
		data = label.FormatMountLabel(m.Data, mountLabel)
	)
	if !strings.HasPrefix(dest, rootfs) {
		dest = filepath.Join(rootfs, dest)
	}

	switch m.Device {
	case "proc", "sysfs":
		if err := os.MkdirAll(dest, 0755); err != nil && !os.IsExist(err) {
			return err
		}
		return syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), "")
	case "mqueue":
		if err := os.MkdirAll(dest, 0755); err != nil && !os.IsExist(err) {
			return err
		}
		if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), ""); err != nil {
			return err
		}
		return label.SetFileLabel(dest, mountLabel)
	case "tmpfs":
		stat, err := os.Stat(dest)
		if err != nil {
			if err := os.MkdirAll(dest, 0755); err != nil && !os.IsExist(err) {
				return err
			}
		}
		if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), data); err != nil {
			return err
		}
		if stat != nil {
			if err = os.Chmod(dest, stat.Mode()); err != nil {
				return err
			}
		}
		return nil
	case "devpts":
		if err := os.MkdirAll(dest, 0755); err != nil && !os.IsExist(err) {
			return err
		}
		return syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), data)
	case "bind":
		stat, err := os.Stat(m.Source)
		if err != nil {
			// error out if the source of a bind mount does not exist as we will be
			// unable to bind anything to it.
			return err
		}
		if err := createIfNotExists(dest, stat.IsDir()); err != nil {
			return err
		}
		if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), data); err != nil {
			return err
		}
		if m.Flags&syscall.MS_RDONLY != 0 {
			if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags|syscall.MS_REMOUNT), ""); err != nil {
				return err
			}
		}
		if m.Relabel != "" {
			if err := label.Relabel(m.Source, mountLabel, m.Relabel); err != nil {
				return err
			}
		}
		if m.Flags&syscall.MS_PRIVATE != 0 {
			if err := syscall.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil {
				return err
			}
		}
	case "cgroup":
		mounts, err := cgroups.GetCgroupMounts()
		if err != nil {
			return err
		}
		var binds []*configs.Mount
		for _, mm := range mounts {
			dir, err := mm.GetThisCgroupDir()
			if err != nil {
				return err
			}
			binds = append(binds, &configs.Mount{
				Device:      "bind",
				Source:      filepath.Join(mm.Mountpoint, dir),
				Destination: filepath.Join(m.Destination, strings.Join(mm.Subsystems, ",")),
				Flags:       syscall.MS_BIND | syscall.MS_REC | syscall.MS_RDONLY,
			})
		}
		tmpfs := &configs.Mount{
			Device:      "tmpfs",
			Destination: m.Destination,
			Flags:       syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV,
		}
		if err := mountToRootfs(tmpfs, rootfs, mountLabel); err != nil {
			return err
		}
		for _, b := range binds {
			if err := mountToRootfs(b, rootfs, mountLabel); err != nil {
				return err
			}
		}
	default:
		return fmt.Errorf("unknown mount device %q to %q", m.Device, m.Destination)
	}
	return nil
}