mirror of
				https://github.com/linuxkit/linuxkit.git
				synced 2025-11-04 16:04:46 +00:00 
			
		
		
		
	Add support for ambient capabilities
Allow setting ambient capabilities, as a seperate option to the standard ones. If you are running as a non root user you should use these. Note that unless you add `CAP_DAC_OVERRIDE` and similar permissions you need to be careful about file ownership. Added support to set ownership in the `files` section to help out with this. Signed-off-by: Justin Cormack <justin.cormack@docker.com>
This commit is contained in:
		@@ -414,6 +414,8 @@ func filesystem(m Moby, tw *tar.Writer) error {
 | 
			
		||||
					Name:     root,
 | 
			
		||||
					Typeflag: tar.TypeDir,
 | 
			
		||||
					Mode:     dirMode,
 | 
			
		||||
					Uid:      int(f.UID),
 | 
			
		||||
					Gid:      int(f.GID),
 | 
			
		||||
				}
 | 
			
		||||
				err := tw.WriteHeader(hdr)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
@@ -423,36 +425,30 @@ func filesystem(m Moby, tw *tar.Writer) error {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		addedFiles[f.Path] = true
 | 
			
		||||
		hdr := &tar.Header{
 | 
			
		||||
			Name: f.Path,
 | 
			
		||||
			Mode: mode,
 | 
			
		||||
			Uid:  int(f.UID),
 | 
			
		||||
			Gid:  int(f.GID),
 | 
			
		||||
		}
 | 
			
		||||
		if f.Directory {
 | 
			
		||||
			if f.Contents != nil {
 | 
			
		||||
				return errors.New("Directory with contents not allowed")
 | 
			
		||||
			}
 | 
			
		||||
			hdr := &tar.Header{
 | 
			
		||||
				Name:     f.Path,
 | 
			
		||||
				Typeflag: tar.TypeDir,
 | 
			
		||||
				Mode:     mode,
 | 
			
		||||
			}
 | 
			
		||||
			hdr.Typeflag = tar.TypeDir
 | 
			
		||||
			err := tw.WriteHeader(hdr)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		} else if f.Symlink != "" {
 | 
			
		||||
			hdr := &tar.Header{
 | 
			
		||||
				Name:     f.Path,
 | 
			
		||||
				Typeflag: tar.TypeSymlink,
 | 
			
		||||
				Mode:     mode,
 | 
			
		||||
				Linkname: f.Symlink,
 | 
			
		||||
			}
 | 
			
		||||
			hdr.Typeflag = tar.TypeSymlink
 | 
			
		||||
			hdr.Linkname = f.Symlink
 | 
			
		||||
			err := tw.WriteHeader(hdr)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			hdr := &tar.Header{
 | 
			
		||||
				Name: f.Path,
 | 
			
		||||
				Mode: mode,
 | 
			
		||||
				Size: int64(len(contents)),
 | 
			
		||||
			}
 | 
			
		||||
			hdr.Size = int64(len(contents))
 | 
			
		||||
			err := tw.WriteHeader(hdr)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
 
 | 
			
		||||
@@ -27,15 +27,7 @@ type Moby struct {
 | 
			
		||||
	Onboot   []Image
 | 
			
		||||
	Services []Image
 | 
			
		||||
	Trust    TrustConfig
 | 
			
		||||
	Files    []struct {
 | 
			
		||||
		Path      string
 | 
			
		||||
		Directory bool
 | 
			
		||||
		Symlink   string
 | 
			
		||||
		Contents  *string
 | 
			
		||||
		Source    string
 | 
			
		||||
		Optional  bool
 | 
			
		||||
		Mode      string
 | 
			
		||||
	}
 | 
			
		||||
	Files    []File
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TrustConfig is the type of a content trust config
 | 
			
		||||
@@ -44,11 +36,25 @@ type TrustConfig struct {
 | 
			
		||||
	Org   []string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// File is the type of a file specification
 | 
			
		||||
type File struct {
 | 
			
		||||
	Path      string
 | 
			
		||||
	Directory bool
 | 
			
		||||
	Symlink   string
 | 
			
		||||
	Contents  *string
 | 
			
		||||
	Source    string
 | 
			
		||||
	Optional  bool
 | 
			
		||||
	Mode      string
 | 
			
		||||
	UID       uint32 `yaml:"uid" json:"uid"`
 | 
			
		||||
	GID       uint32 `yaml:"gid" json:"gid"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Image is the type of an image config
 | 
			
		||||
type Image struct {
 | 
			
		||||
	Name              string             `yaml:"name" json:"name"`
 | 
			
		||||
	Image             string             `yaml:"image" json:"image"`
 | 
			
		||||
	Capabilities      *[]string          `yaml:"capabilities" json:"capabilities,omitempty"`
 | 
			
		||||
	Ambient           *[]string          `yaml:"ambient" json:"ambient,omitempty"`
 | 
			
		||||
	Mounts            *[]specs.Mount     `yaml:"mounts" json:"mounts,omitempty"`
 | 
			
		||||
	Binds             *[]string          `yaml:"binds" json:"binds,omitempty"`
 | 
			
		||||
	Tmpfs             *[]string          `yaml:"tmpfs" json:"tmpfs,omitempty"`
 | 
			
		||||
@@ -619,25 +625,13 @@ func ConfigInspectToOCI(yaml Image, inspect types.ImageInspect) (specs.Spec, err
 | 
			
		||||
 | 
			
		||||
	// TODO user, cgroup namespaces
 | 
			
		||||
 | 
			
		||||
	caps := assignStrings(label.Capabilities, yaml.Capabilities)
 | 
			
		||||
	for _, capability := range caps {
 | 
			
		||||
		if capability == "none" || capability == "all" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		found := false
 | 
			
		||||
		for _, ac := range allCaps {
 | 
			
		||||
			if ac == capability {
 | 
			
		||||
				found = true
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !found {
 | 
			
		||||
			return oci, fmt.Errorf("unknown capability: %s", capability)
 | 
			
		||||
		}
 | 
			
		||||
	// Capabilities
 | 
			
		||||
	capCheck := map[string]bool{}
 | 
			
		||||
	for _, capability := range allCaps {
 | 
			
		||||
		capCheck[capability] = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	boundingSet := map[string]bool{}
 | 
			
		||||
	caps := assignStrings(label.Capabilities, yaml.Capabilities)
 | 
			
		||||
	if len(caps) == 1 {
 | 
			
		||||
		switch cap := strings.ToLower(caps[0]); cap {
 | 
			
		||||
		case "none":
 | 
			
		||||
@@ -646,6 +640,31 @@ func ConfigInspectToOCI(yaml Image, inspect types.ImageInspect) (specs.Spec, err
 | 
			
		||||
			caps = allCaps[:]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for _, capability := range caps {
 | 
			
		||||
		if !capCheck[capability] {
 | 
			
		||||
			return oci, fmt.Errorf("unknown capability: %s", capability)
 | 
			
		||||
		}
 | 
			
		||||
		boundingSet[capability] = true
 | 
			
		||||
	}
 | 
			
		||||
	ambient := assignStrings(label.Ambient, yaml.Ambient)
 | 
			
		||||
	if len(ambient) == 1 {
 | 
			
		||||
		switch cap := strings.ToLower(ambient[0]); cap {
 | 
			
		||||
		case "none":
 | 
			
		||||
			ambient = []string{}
 | 
			
		||||
		case "all":
 | 
			
		||||
			ambient = allCaps[:]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for _, capability := range ambient {
 | 
			
		||||
		if !capCheck[capability] {
 | 
			
		||||
			return oci, fmt.Errorf("unknown capability: %s", capability)
 | 
			
		||||
		}
 | 
			
		||||
		boundingSet[capability] = true
 | 
			
		||||
	}
 | 
			
		||||
	bounding := []string{}
 | 
			
		||||
	for capability := range boundingSet {
 | 
			
		||||
		bounding = append(bounding, capability)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rlimitsString := assignStrings(label.Rlimits, yaml.Rlimits)
 | 
			
		||||
	rlimits := []specs.LinuxRlimit{}
 | 
			
		||||
@@ -727,11 +746,11 @@ func ConfigInspectToOCI(yaml Image, inspect types.ImageInspect) (specs.Spec, err
 | 
			
		||||
		Env:  env,
 | 
			
		||||
		Cwd:  cwd,
 | 
			
		||||
		Capabilities: &specs.LinuxCapabilities{
 | 
			
		||||
			Bounding:    caps,
 | 
			
		||||
			Bounding:    bounding,
 | 
			
		||||
			Effective:   caps,
 | 
			
		||||
			Inheritable: caps,
 | 
			
		||||
			Permitted:   caps,
 | 
			
		||||
			Ambient:     []string{},
 | 
			
		||||
			Inheritable: bounding,
 | 
			
		||||
			Permitted:   bounding,
 | 
			
		||||
			Ambient:     ambient,
 | 
			
		||||
		},
 | 
			
		||||
		Rlimits:         rlimits,
 | 
			
		||||
		NoNewPrivileges: assignBool(label.NoNewPrivileges, yaml.NoNewPrivileges),
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,9 @@ var schema = string(`
 | 
			
		||||
          "contents": {"type": "string"},
 | 
			
		||||
          "source": {"type": "string"},
 | 
			
		||||
          "optional": {"type": "boolean"},
 | 
			
		||||
          "mode": {"type": "string"}
 | 
			
		||||
          "mode": {"type": "string"},
 | 
			
		||||
          "uid": {"type": "integer"},
 | 
			
		||||
          "gid": {"type": "integer"}
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "files": {
 | 
			
		||||
@@ -65,6 +67,7 @@ var schema = string(`
 | 
			
		||||
        "name": {"type": "string"},
 | 
			
		||||
        "image": {"type": "string"},
 | 
			
		||||
        "capabilities": { "$ref": "#/definitions/strings" },
 | 
			
		||||
        "ambient": { "$ref": "#/definitions/strings" },
 | 
			
		||||
        "mounts": { "$ref": "#/definitions/mounts" },
 | 
			
		||||
        "binds": { "$ref": "#/definitions/strings" },
 | 
			
		||||
        "tmpfs": { "$ref": "#/definitions/strings" },
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user