Ejemplo n.º 1
0
func createDevices(spec *LinuxSpec, config *configs.Config) error {
	for _, name := range spec.Devices {
		d, err := devices.DeviceFromPath(filepath.Join("/dev", name), "rwm")
		if err != nil {
			return err
		}
		config.Devices = append(config.Devices, d)
	}
	return nil
}
Ejemplo n.º 2
0
func (d *Driver) setPrivileged(container *configs.Config) (err error) {
	container.Capabilities = execdriver.GetAllCapabilities()
	container.Cgroups.AllowAllDevices = true

	hostDevices, err := devices.HostDevices()
	if err != nil {
		return err
	}
	container.Devices = hostDevices

	if apparmor.IsEnabled() {
		container.AppArmorProfile = "unconfined"
	}
	return nil
}
Ejemplo n.º 3
0
func (r *libcontainerRuntime) createDevices(spec *specs.LinuxRuntimeSpec, config *configs.Config) error {
	for _, d := range spec.Linux.Devices {
		device := &configs.Device{
			Type:        d.Type,
			Path:        d.Path,
			Major:       d.Major,
			Minor:       d.Minor,
			Permissions: d.Permissions,
			FileMode:    d.FileMode,
			Uid:         d.UID,
			Gid:         d.GID,
		}
		config.Devices = append(config.Devices, device)
	}
	return nil
}
Ejemplo n.º 4
0
func (d *Driver) setupMounts(container *configs.Config, c *execdriver.Command) error {
	userMounts := make(map[string]struct{})
	for _, m := range c.Mounts {
		userMounts[m.Destination] = struct{}{}
	}

	// Filter out mounts that are overriden by user supplied mounts
	var defaultMounts []*configs.Mount
	_, mountDev := userMounts["/dev"]
	for _, m := range container.Mounts {
		if _, ok := userMounts[m.Destination]; !ok {
			if mountDev && strings.HasPrefix(m.Destination, "/dev/") {
				container.Devices = nil
				continue
			}
			defaultMounts = append(defaultMounts, m)
		}
	}
	container.Mounts = defaultMounts

	for _, m := range c.Mounts {
		flags := syscall.MS_BIND | syscall.MS_REC
		if !m.Writable {
			flags |= syscall.MS_RDONLY
		}
		if m.Slave {
			flags |= syscall.MS_SLAVE
		}

		container.Mounts = append(container.Mounts, &configs.Mount{
			Source:      m.Source,
			Destination: m.Destination,
			Device:      "bind",
			Flags:       flags,
		})
	}
	return nil
}
Ejemplo n.º 5
0
func createDevices(spec *specs.Spec, config *configs.Config) error {
	// add whitelisted devices
	config.Devices = []*configs.Device{
		{
			Type:     'c',
			Path:     "/dev/null",
			Major:    1,
			Minor:    3,
			FileMode: 0666,
			Uid:      0,
			Gid:      0,
		},
		{
			Type:     'c',
			Path:     "/dev/random",
			Major:    1,
			Minor:    8,
			FileMode: 0666,
			Uid:      0,
			Gid:      0,
		},
		{
			Type:     'c',
			Path:     "/dev/full",
			Major:    1,
			Minor:    7,
			FileMode: 0666,
			Uid:      0,
			Gid:      0,
		},
		{
			Type:     'c',
			Path:     "/dev/tty",
			Major:    5,
			Minor:    0,
			FileMode: 0666,
			Uid:      0,
			Gid:      0,
		},
		{
			Type:     'c',
			Path:     "/dev/zero",
			Major:    1,
			Minor:    5,
			FileMode: 0666,
			Uid:      0,
			Gid:      0,
		},
		{
			Type:     'c',
			Path:     "/dev/urandom",
			Major:    1,
			Minor:    9,
			FileMode: 0666,
			Uid:      0,
			Gid:      0,
		},
	}
	// merge in additional devices from the spec
	for _, d := range spec.Linux.Devices {
		var uid, gid uint32
		if d.UID != nil {
			uid = *d.UID
		}
		if d.GID != nil {
			gid = *d.GID
		}
		dt, err := stringToDeviceRune(d.Type)
		if err != nil {
			return err
		}
		device := &configs.Device{
			Type:     dt,
			Path:     d.Path,
			Major:    d.Major,
			Minor:    d.Minor,
			FileMode: *d.FileMode,
			Uid:      uid,
			Gid:      gid,
		}
		config.Devices = append(config.Devices, device)
	}
	return nil
}
Ejemplo n.º 6
0
func (d *Driver) setupMounts(container *configs.Config, c *execdriver.Command) error {
	userMounts := make(map[string]struct{})
	for _, m := range c.Mounts {
		userMounts[m.Destination] = struct{}{}
	}

	// Filter out mounts that are overridden by user supplied mounts
	var defaultMounts []*configs.Mount
	_, mountDev := userMounts["/dev"]
	for _, m := range container.Mounts {
		if _, ok := userMounts[m.Destination]; !ok {
			if mountDev && strings.HasPrefix(m.Destination, "/dev/") {
				container.Devices = nil
				continue
			}
			defaultMounts = append(defaultMounts, m)
		}
	}
	container.Mounts = defaultMounts

	mountPropagationMap := map[string]int{
		"private":  mount.PRIVATE,
		"rprivate": mount.RPRIVATE,
		"shared":   mount.SHARED,
		"rshared":  mount.RSHARED,
		"slave":    mount.SLAVE,
		"rslave":   mount.RSLAVE,
	}

	for _, m := range c.Mounts {
		for _, cm := range container.Mounts {
			if cm.Destination == m.Destination {
				return derr.ErrorCodeMountDup.WithArgs(m.Destination)
			}
		}

		if m.Source == "tmpfs" {
			var (
				data  = "size=65536k"
				flags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV
				err   error
			)
			if m.Data != "" {
				flags, data, err = mount.ParseTmpfsOptions(m.Data)
				if err != nil {
					return err
				}
			}
			container.Mounts = append(container.Mounts, &configs.Mount{
				Source:           m.Source,
				Destination:      m.Destination,
				Data:             data,
				Device:           "tmpfs",
				Flags:            flags,
				PropagationFlags: []int{mountPropagationMap[volume.DefaultPropagationMode]},
			})
			continue
		}
		flags := syscall.MS_BIND | syscall.MS_REC
		var pFlag int
		if !m.Writable {
			flags |= syscall.MS_RDONLY
		}

		// Determine property of RootPropagation based on volume
		// properties. If a volume is shared, then keep root propagtion
		// shared. This should work for slave and private volumes too.
		//
		// For slave volumes, it can be either [r]shared/[r]slave.
		//
		// For private volumes any root propagation value should work.

		pFlag = mountPropagationMap[m.Propagation]
		if pFlag == mount.SHARED || pFlag == mount.RSHARED {
			if err := ensureShared(m.Source); err != nil {
				return err
			}
			rootpg := container.RootPropagation
			if rootpg != mount.SHARED && rootpg != mount.RSHARED {
				execdriver.SetRootPropagation(container, mount.SHARED)
			}
		} else if pFlag == mount.SLAVE || pFlag == mount.RSLAVE {
			if err := ensureSharedOrSlave(m.Source); err != nil {
				return err
			}
			rootpg := container.RootPropagation
			if rootpg != mount.SHARED && rootpg != mount.RSHARED && rootpg != mount.SLAVE && rootpg != mount.RSLAVE {
				execdriver.SetRootPropagation(container, mount.RSLAVE)
			}
		}

		mount := &configs.Mount{
			Source:      m.Source,
			Destination: m.Destination,
			Device:      "bind",
			Flags:       flags,
		}

		if pFlag != 0 {
			mount.PropagationFlags = []int{pFlag}
		}

		container.Mounts = append(container.Mounts, mount)
	}

	checkResetVolumePropagation(container)
	return nil
}
Ejemplo n.º 7
0
func (d *Driver) setupMounts(container *configs.Config, c *execdriver.Command) error {
	userMounts := make(map[string]struct{})
	for _, m := range c.Mounts {
		userMounts[m.Destination] = struct{}{}
	}

	// Filter out mounts that are overriden by user supplied mounts
	var defaultMounts []*configs.Mount
	_, mountDev := userMounts["/dev"]
	for _, m := range container.Mounts {
		if _, ok := userMounts[m.Destination]; !ok {
			if mountDev && strings.HasPrefix(m.Destination, "/dev/") {
				container.Devices = nil
				continue
			}
			defaultMounts = append(defaultMounts, m)
		}
	}
	container.Mounts = defaultMounts

	for _, m := range c.Mounts {
		for _, cm := range container.Mounts {
			if cm.Destination == m.Destination {
				return derr.ErrorCodeMountDup.WithArgs(m.Destination)
			}
		}

		if m.Source == "tmpfs" {
			var (
				data  = "size=65536k"
				flags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV
				err   error
			)
			fulldest := filepath.Join(c.Rootfs, m.Destination)
			if m.Data != "" {
				flags, data, err = mount.ParseTmpfsOptions(m.Data)
				if err != nil {
					return err
				}
			}
			container.Mounts = append(container.Mounts, &configs.Mount{
				Source:        m.Source,
				Destination:   m.Destination,
				Data:          data,
				Device:        "tmpfs",
				Flags:         flags,
				PremountCmds:  genTmpfsPremountCmd(c.TmpDir, fulldest, m.Destination),
				PostmountCmds: genTmpfsPostmountCmd(c.TmpDir, fulldest, m.Destination),
			})
			continue
		}
		flags := syscall.MS_BIND | syscall.MS_REC
		if !m.Writable {
			flags |= syscall.MS_RDONLY
		}
		if m.Slave {
			flags |= syscall.MS_SLAVE
		}

		container.Mounts = append(container.Mounts, &configs.Mount{
			Source:      m.Source,
			Destination: m.Destination,
			Device:      "bind",
			Flags:       flags,
		})
	}
	return nil
}