github.com/containers/podman/v4@v4.9.4/pkg/specgen/generate/kube/seccomp.go (about)

     1  //go:build !remote
     2  // +build !remote
     3  
     4  package kube
     5  
     6  import (
     7  	"fmt"
     8  	"path/filepath"
     9  	"strings"
    10  
    11  	"github.com/containers/podman/v4/libpod"
    12  	v1 "github.com/containers/podman/v4/pkg/k8s.io/api/core/v1"
    13  )
    14  
    15  // KubeSeccompPaths holds information about a pod YAML's seccomp configuration
    16  // it holds both container and pod seccomp paths
    17  //
    18  //nolint:revive
    19  type KubeSeccompPaths struct {
    20  	containerPaths map[string]string
    21  	podPath        string
    22  }
    23  
    24  // FindForContainer checks whether a container has a seccomp path configured for it
    25  // if not, it returns the podPath, which should always have a value
    26  func (k *KubeSeccompPaths) FindForContainer(ctrName string) string {
    27  	if path, ok := k.containerPaths[ctrName]; ok {
    28  		return path
    29  	}
    30  	return k.podPath
    31  }
    32  
    33  // InitializeSeccompPaths takes annotations from the pod object metadata and finds annotations pertaining to seccomp
    34  // it parses both pod and container level
    35  // if the annotation is of the form "localhost/%s", the seccomp profile will be set to profileRoot/%s
    36  func InitializeSeccompPaths(annotations map[string]string, profileRoot string) (*KubeSeccompPaths, error) {
    37  	seccompPaths := &KubeSeccompPaths{containerPaths: make(map[string]string)}
    38  	var err error
    39  	if annotations != nil {
    40  		for annKeyValue, seccomp := range annotations {
    41  			// check if it is prefaced with container.seccomp.security.alpha.kubernetes.io/
    42  			prefixAndCtr := strings.Split(annKeyValue, "/")
    43  			if prefixAndCtr[0]+"/" != v1.SeccompContainerAnnotationKeyPrefix {
    44  				continue
    45  			} else if len(prefixAndCtr) != 2 {
    46  				// this could be caused by a user inputting either of
    47  				// container.seccomp.security.alpha.kubernetes.io{,/}
    48  				// both of which are invalid
    49  				return nil, fmt.Errorf("invalid seccomp path: %s", prefixAndCtr[0])
    50  			}
    51  
    52  			path, err := verifySeccompPath(seccomp, profileRoot)
    53  			if err != nil {
    54  				return nil, err
    55  			}
    56  			seccompPaths.containerPaths[prefixAndCtr[1]] = path
    57  		}
    58  
    59  		podSeccomp, ok := annotations[v1.SeccompPodAnnotationKey]
    60  		if ok {
    61  			seccompPaths.podPath, err = verifySeccompPath(podSeccomp, profileRoot)
    62  		} else {
    63  			seccompPaths.podPath, err = libpod.DefaultSeccompPath()
    64  		}
    65  		if err != nil {
    66  			return nil, err
    67  		}
    68  	}
    69  	return seccompPaths, nil
    70  }
    71  
    72  // verifySeccompPath takes a path and checks whether it is a default, unconfined, or a path
    73  // the available options are parsed as defined in https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp
    74  func verifySeccompPath(path string, profileRoot string) (string, error) {
    75  	switch path {
    76  	case v1.DeprecatedSeccompProfileDockerDefault:
    77  		fallthrough
    78  	case v1.SeccompProfileRuntimeDefault:
    79  		return libpod.DefaultSeccompPath()
    80  	case "unconfined":
    81  		return path, nil
    82  	default:
    83  		parts := strings.Split(path, "/")
    84  		if parts[0] == "localhost" {
    85  			return filepath.Join(profileRoot, parts[1]), nil
    86  		}
    87  		return "", fmt.Errorf("invalid seccomp path: %s", path)
    88  	}
    89  }