github.com/jfrazelle/docker@v1.1.2-0.20210712172922-bf78e25fe508/profiles/seccomp/seccomp.go (about)

     1  package seccomp // import "github.com/docker/docker/profiles/seccomp"
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/opencontainers/runtime-spec/specs-go"
    10  )
    11  
    12  // Seccomp represents the config for a seccomp profile for syscall restriction.
    13  type Seccomp struct {
    14  	DefaultAction specs.LinuxSeccompAction `json:"defaultAction"`
    15  	// Architectures is kept to maintain backward compatibility with the old
    16  	// seccomp profile.
    17  	Architectures []specs.Arch   `json:"architectures,omitempty"`
    18  	ArchMap       []Architecture `json:"archMap,omitempty"`
    19  	Syscalls      []*Syscall     `json:"syscalls"`
    20  }
    21  
    22  // Architecture is used to represent a specific architecture
    23  // and its sub-architectures
    24  type Architecture struct {
    25  	Arch      specs.Arch   `json:"architecture"`
    26  	SubArches []specs.Arch `json:"subArchitectures"`
    27  }
    28  
    29  // Filter is used to conditionally apply Seccomp rules
    30  type Filter struct {
    31  	Caps   []string `json:"caps,omitempty"`
    32  	Arches []string `json:"arches,omitempty"`
    33  
    34  	// MinKernel describes the minimum kernel version the rule must be applied
    35  	// on, in the format "<kernel version>.<major revision>" (e.g. "3.12").
    36  	//
    37  	// When matching the kernel version of the host, minor revisions, and distro-
    38  	// specific suffixes are ignored, which means that "3.12.25-gentoo", "3.12-1-amd64",
    39  	// "3.12", and "3.12-rc5" are considered equal (kernel 3, major revision 12).
    40  	MinKernel *KernelVersion `json:"minKernel,omitempty"`
    41  }
    42  
    43  // Syscall is used to match a group of syscalls in Seccomp. It extends the
    44  // runtime-spec Syscall type, adding a "Name" field for backward compatibility
    45  // with older JSON representations, additional "Comment" metadata, and conditional
    46  // rules ("Includes", "Excludes") used to generate a runtime-spec Seccomp profile
    47  // based on the container (capabilities) and host's (arch, kernel) configuration.
    48  type Syscall struct {
    49  	specs.LinuxSyscall
    50  	// Deprecated: kept for backward compatibility with old JSON profiles, use Names instead
    51  	Name     string  `json:"name,omitempty"`
    52  	Comment  string  `json:"comment,omitempty"`
    53  	Includes *Filter `json:"includes,omitempty"`
    54  	Excludes *Filter `json:"excludes,omitempty"`
    55  }
    56  
    57  // KernelVersion holds information about the kernel.
    58  type KernelVersion struct {
    59  	Kernel uint64 // Version of the Kernel (i.e., the "4" in "4.1.2-generic")
    60  	Major  uint64 // Major revision of the Kernel (i.e., the "1" in "4.1.2-generic")
    61  }
    62  
    63  // String implements fmt.Stringer for KernelVersion
    64  func (k *KernelVersion) String() string {
    65  	if k.Kernel > 0 || k.Major > 0 {
    66  		return fmt.Sprintf("%d.%d", k.Kernel, k.Major)
    67  	}
    68  	return ""
    69  }
    70  
    71  // MarshalJSON implements json.Unmarshaler for KernelVersion
    72  func (k *KernelVersion) MarshalJSON() ([]byte, error) {
    73  	return json.Marshal(k.String())
    74  }
    75  
    76  // UnmarshalJSON implements json.Marshaler for KernelVersion
    77  func (k *KernelVersion) UnmarshalJSON(version []byte) error {
    78  	var (
    79  		ver string
    80  		err error
    81  	)
    82  
    83  	// make sure we have a string
    84  	if err = json.Unmarshal(version, &ver); err != nil {
    85  		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>": %v`, string(version), err)
    86  	}
    87  	if ver == "" {
    88  		return nil
    89  	}
    90  	parts := strings.SplitN(ver, ".", 3)
    91  	if len(parts) != 2 {
    92  		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>"`, string(version))
    93  	}
    94  	if k.Kernel, err = strconv.ParseUint(parts[0], 10, 8); err != nil {
    95  		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>": %v`, string(version), err)
    96  	}
    97  	if k.Major, err = strconv.ParseUint(parts[1], 10, 8); err != nil {
    98  		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>": %v`, string(version), err)
    99  	}
   100  	if k.Kernel == 0 && k.Major == 0 {
   101  		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>": version cannot be 0.0`, string(version))
   102  	}
   103  	return nil
   104  }