github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/moby/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
    44  type Syscall struct {
    45  	Name     string                   `json:"name,omitempty"`
    46  	Names    []string                 `json:"names,omitempty"`
    47  	Action   specs.LinuxSeccompAction `json:"action"`
    48  	Args     []*specs.LinuxSeccompArg `json:"args"`
    49  	Comment  string                   `json:"comment"`
    50  	Includes Filter                   `json:"includes"`
    51  	Excludes Filter                   `json:"excludes"`
    52  }
    53  
    54  // KernelVersion holds information about the kernel.
    55  type KernelVersion struct {
    56  	Kernel uint64 // Version of the Kernel (i.e., the "4" in "4.1.2-generic")
    57  	Major  uint64 // Major revision of the Kernel (i.e., the "1" in "4.1.2-generic")
    58  }
    59  
    60  // String implements fmt.Stringer for KernelVersion
    61  func (k *KernelVersion) String() string {
    62  	if k.Kernel > 0 || k.Major > 0 {
    63  		return fmt.Sprintf("%d.%d", k.Kernel, k.Major)
    64  	}
    65  	return ""
    66  }
    67  
    68  // MarshalJSON implements json.Unmarshaler for KernelVersion
    69  func (k *KernelVersion) MarshalJSON() ([]byte, error) {
    70  	return json.Marshal(k.String())
    71  }
    72  
    73  // UnmarshalJSON implements json.Marshaler for KernelVersion
    74  func (k *KernelVersion) UnmarshalJSON(version []byte) error {
    75  	var (
    76  		ver string
    77  		err error
    78  	)
    79  
    80  	// make sure we have a string
    81  	if err = json.Unmarshal(version, &ver); err != nil {
    82  		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>": %v`, string(version), err)
    83  	}
    84  	if ver == "" {
    85  		return nil
    86  	}
    87  	parts := strings.SplitN(ver, ".", 3)
    88  	if len(parts) != 2 {
    89  		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>"`, string(version))
    90  	}
    91  	if k.Kernel, err = strconv.ParseUint(parts[0], 10, 8); err != nil {
    92  		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>": %v`, string(version), err)
    93  	}
    94  	if k.Major, err = strconv.ParseUint(parts[1], 10, 8); err != nil {
    95  		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>": %v`, string(version), err)
    96  	}
    97  	if k.Kernel == 0 && k.Major == 0 {
    98  		return fmt.Errorf(`invalid kernel version: %s, expected "<kernel>.<major>": version cannot be 0.0`, string(version))
    99  	}
   100  	return nil
   101  }