nri: add experimental NRI plugin.

Add a common NRI 'service' plugin. It takes care of relaying
requests and respones to and from NRI (external NRI plugins)
and the high-level containerd namespace-independent logic of
applying NRI container adjustments and updates to actual CRI
and other containers.

The namespace-dependent details of the necessary container
manipulation operations are to be implemented by namespace-
specific adaptations. This NRI plugin defines the API which
such adaptations need to implement.

Signed-off-by: Krisztian Litkey <krisztian.litkey@intel.com>
This commit is contained in:
Krisztian Litkey
2022-08-31 16:10:24 +03:00
parent e0be97ccee
commit 43704ca888
118 changed files with 12178 additions and 10066 deletions

View File

@@ -123,6 +123,13 @@ func (g *Generator) initConfigLinuxResourcesPids() {
}
}
func (g *Generator) initConfigLinuxResourcesUnified() {
g.initConfigLinuxResources()
if g.Config.Linux.Resources.Unified == nil {
g.Config.Linux.Resources.Unified = map[string]string{}
}
}
func (g *Generator) initConfigSolaris() {
g.initConfig()
if g.Config.Solaris == nil {
@@ -185,24 +192,3 @@ func (g *Generator) initConfigVM() {
g.Config.VM = &rspec.VM{}
}
}
func (g *Generator) initConfigVMHypervisor() {
g.initConfigVM()
if &g.Config.VM.Hypervisor == nil {
g.Config.VM.Hypervisor = rspec.VMHypervisor{}
}
}
func (g *Generator) initConfigVMKernel() {
g.initConfigVM()
if &g.Config.VM.Kernel == nil {
g.Config.VM.Kernel = rspec.VMKernel{}
}
}
func (g *Generator) initConfigVMImage() {
g.initConfigVM()
if &g.Config.VM.Image == nil {
g.Config.VM.Image = rspec.VMImage{}
}
}

View File

@@ -10,7 +10,7 @@ import (
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate/seccomp"
"github.com/opencontainers/runtime-tools/validate"
capsCheck "github.com/opencontainers/runtime-tools/validate/capabilities"
"github.com/syndtr/gocapability/capability"
)
@@ -42,7 +42,7 @@ type ExportOptions struct {
// New creates a configuration Generator with the default
// configuration for the target operating system.
func New(os string) (generator Generator, err error) {
if os != "linux" && os != "solaris" && os != "windows" {
if os != "linux" && os != "solaris" && os != "windows" && os != "freebsd" {
return generator, fmt.Errorf("no defaults configured for %s", os)
}
@@ -72,7 +72,7 @@ func New(os string) (generator Generator, err error) {
}
}
if os == "linux" || os == "solaris" {
if os == "linux" || os == "solaris" || os == "freebsd" {
config.Process.User = rspec.User{}
config.Process.Env = []string{
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
@@ -182,7 +182,7 @@ func New(os string) (generator Generator, err error) {
Destination: "/dev",
Type: "tmpfs",
Source: "tmpfs",
Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"},
Options: []string{"nosuid", "noexec", "strictatime", "mode=755", "size=65536k"},
},
{
Destination: "/dev/pts",
@@ -237,6 +237,21 @@ func New(os string) (generator Generator, err error) {
},
Seccomp: seccomp.DefaultProfile(&config),
}
} else if os == "freebsd" {
config.Mounts = []rspec.Mount{
{
Destination: "/dev",
Type: "devfs",
Source: "devfs",
Options: []string{"ruleset=4"},
},
{
Destination: "/dev/fd",
Type: "fdescfs",
Source: "fdesc",
Options: []string{},
},
}
}
envCache := map[string]int{}
@@ -249,10 +264,6 @@ func New(os string) (generator Generator, err error) {
// NewFromSpec creates a configuration Generator from a given
// configuration.
//
// Deprecated: Replace with:
//
// generator := Generator{Config: config}
func NewFromSpec(config *rspec.Spec) Generator {
envCache := map[string]int{}
if config != nil && config.Process != nil {
@@ -444,6 +455,13 @@ func (g *Generator) SetProcessUsername(username string) {
g.Config.Process.User.Username = username
}
// SetProcessUmask sets g.Config.Process.User.Umask.
func (g *Generator) SetProcessUmask(umask uint32) {
g.initConfigProcess()
u := umask
g.Config.Process.User.Umask = &u
}
// SetProcessGID sets g.Config.Process.User.GID.
func (g *Generator) SetProcessGID(gid uint32) {
g.initConfigProcess()
@@ -597,6 +615,12 @@ func (g *Generator) SetLinuxCgroupsPath(path string) {
g.Config.Linux.CgroupsPath = path
}
// SetLinuxIntelRdtClosID sets g.Config.Linux.IntelRdt.ClosID
func (g *Generator) SetLinuxIntelRdtClosID(clos string) {
g.initConfigLinuxIntelRdt()
g.Config.Linux.IntelRdt.ClosID = clos
}
// SetLinuxIntelRdtL3CacheSchema sets g.Config.Linux.IntelRdt.L3CacheSchema
func (g *Generator) SetLinuxIntelRdtL3CacheSchema(schema string) {
g.initConfigLinuxIntelRdt()
@@ -844,6 +868,28 @@ func (g *Generator) DropLinuxResourcesHugepageLimit(pageSize string) {
}
}
// AddLinuxResourcesUnified sets the g.Config.Linux.Resources.Unified
func (g *Generator) SetLinuxResourcesUnified(unified map[string]string) {
g.initConfigLinuxResourcesUnified()
for k, v := range unified {
g.Config.Linux.Resources.Unified[k] = v
}
}
// AddLinuxResourcesUnified adds or updates the key-value pair from g.Config.Linux.Resources.Unified
func (g *Generator) AddLinuxResourcesUnified(key, val string) {
g.initConfigLinuxResourcesUnified()
g.Config.Linux.Resources.Unified[key] = val
}
// DropLinuxResourcesUnified drops a key-value pair from g.Config.Linux.Resources.Unified
func (g *Generator) DropLinuxResourcesUnified(key string) {
if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.Unified == nil {
return
}
delete(g.Config.Linux.Resources.Unified, key)
}
// SetLinuxResourcesMemoryLimit sets g.Config.Linux.Resources.Memory.Limit.
func (g *Generator) SetLinuxResourcesMemoryLimit(limit int64) {
g.initConfigLinuxResourcesMemory()
@@ -1018,10 +1064,9 @@ func (g *Generator) ClearPreStartHooks() {
}
// AddPreStartHook add a prestart hook into g.Config.Hooks.Prestart.
func (g *Generator) AddPreStartHook(preStartHook rspec.Hook) error {
func (g *Generator) AddPreStartHook(preStartHook rspec.Hook) {
g.initConfigHooks()
g.Config.Hooks.Prestart = append(g.Config.Hooks.Prestart, preStartHook)
return nil
}
// ClearPostStopHooks clear g.Config.Hooks.Poststop.
@@ -1033,10 +1078,9 @@ func (g *Generator) ClearPostStopHooks() {
}
// AddPostStopHook adds a poststop hook into g.Config.Hooks.Poststop.
func (g *Generator) AddPostStopHook(postStopHook rspec.Hook) error {
func (g *Generator) AddPostStopHook(postStopHook rspec.Hook) {
g.initConfigHooks()
g.Config.Hooks.Poststop = append(g.Config.Hooks.Poststop, postStopHook)
return nil
}
// ClearPostStartHooks clear g.Config.Hooks.Poststart.
@@ -1048,10 +1092,9 @@ func (g *Generator) ClearPostStartHooks() {
}
// AddPostStartHook adds a poststart hook into g.Config.Hooks.Poststart.
func (g *Generator) AddPostStartHook(postStartHook rspec.Hook) error {
func (g *Generator) AddPostStartHook(postStartHook rspec.Hook) {
g.initConfigHooks()
g.Config.Hooks.Poststart = append(g.Config.Hooks.Poststart, postStartHook)
return nil
}
// AddMount adds a mount into g.Config.Mounts.
@@ -1093,7 +1136,7 @@ func (g *Generator) SetupPrivileged(privileged bool) {
if privileged { // Add all capabilities in privileged mode.
var finalCapList []string
for _, cap := range capability.List() {
if g.HostSpecific && cap > validate.LastCap() {
if g.HostSpecific && cap > capsCheck.LastCap() {
continue
}
finalCapList = append(finalCapList, fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String())))
@@ -1127,7 +1170,7 @@ func (g *Generator) ClearProcessCapabilities() {
// AddProcessCapability adds a process capability into all 5 capability sets.
func (g *Generator) AddProcessCapability(c string) error {
cp := strings.ToUpper(c)
if err := validate.CapValid(cp, g.HostSpecific); err != nil {
if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil {
return err
}
@@ -1190,7 +1233,7 @@ func (g *Generator) AddProcessCapability(c string) error {
// AddProcessCapabilityAmbient adds a process capability into g.Config.Process.Capabilities.Ambient.
func (g *Generator) AddProcessCapabilityAmbient(c string) error {
cp := strings.ToUpper(c)
if err := validate.CapValid(cp, g.HostSpecific); err != nil {
if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil {
return err
}
@@ -1214,7 +1257,7 @@ func (g *Generator) AddProcessCapabilityAmbient(c string) error {
// AddProcessCapabilityBounding adds a process capability into g.Config.Process.Capabilities.Bounding.
func (g *Generator) AddProcessCapabilityBounding(c string) error {
cp := strings.ToUpper(c)
if err := validate.CapValid(cp, g.HostSpecific); err != nil {
if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil {
return err
}
@@ -1237,7 +1280,7 @@ func (g *Generator) AddProcessCapabilityBounding(c string) error {
// AddProcessCapabilityEffective adds a process capability into g.Config.Process.Capabilities.Effective.
func (g *Generator) AddProcessCapabilityEffective(c string) error {
cp := strings.ToUpper(c)
if err := validate.CapValid(cp, g.HostSpecific); err != nil {
if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil {
return err
}
@@ -1260,7 +1303,7 @@ func (g *Generator) AddProcessCapabilityEffective(c string) error {
// AddProcessCapabilityInheritable adds a process capability into g.Config.Process.Capabilities.Inheritable.
func (g *Generator) AddProcessCapabilityInheritable(c string) error {
cp := strings.ToUpper(c)
if err := validate.CapValid(cp, g.HostSpecific); err != nil {
if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil {
return err
}
@@ -1283,7 +1326,7 @@ func (g *Generator) AddProcessCapabilityInheritable(c string) error {
// AddProcessCapabilityPermitted adds a process capability into g.Config.Process.Capabilities.Permitted.
func (g *Generator) AddProcessCapabilityPermitted(c string) error {
cp := strings.ToUpper(c)
if err := validate.CapValid(cp, g.HostSpecific); err != nil {
if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil {
return err
}
@@ -1336,7 +1379,7 @@ func (g *Generator) DropProcessCapability(c string) error {
}
}
return validate.CapValid(cp, false)
return capsCheck.CapValid(cp, false)
}
// DropProcessCapabilityAmbient drops a process capability from g.Config.Process.Capabilities.Ambient.
@@ -1352,7 +1395,7 @@ func (g *Generator) DropProcessCapabilityAmbient(c string) error {
}
}
return validate.CapValid(cp, false)
return capsCheck.CapValid(cp, false)
}
// DropProcessCapabilityBounding drops a process capability from g.Config.Process.Capabilities.Bounding.
@@ -1368,7 +1411,7 @@ func (g *Generator) DropProcessCapabilityBounding(c string) error {
}
}
return validate.CapValid(cp, false)
return capsCheck.CapValid(cp, false)
}
// DropProcessCapabilityEffective drops a process capability from g.Config.Process.Capabilities.Effective.
@@ -1384,7 +1427,7 @@ func (g *Generator) DropProcessCapabilityEffective(c string) error {
}
}
return validate.CapValid(cp, false)
return capsCheck.CapValid(cp, false)
}
// DropProcessCapabilityInheritable drops a process capability from g.Config.Process.Capabilities.Inheritable.
@@ -1400,7 +1443,7 @@ func (g *Generator) DropProcessCapabilityInheritable(c string) error {
}
}
return validate.CapValid(cp, false)
return capsCheck.CapValid(cp, false)
}
// DropProcessCapabilityPermitted drops a process capability from g.Config.Process.Capabilities.Permitted.
@@ -1416,7 +1459,7 @@ func (g *Generator) DropProcessCapabilityPermitted(c string) error {
}
}
return validate.CapValid(cp, false)
return capsCheck.CapValid(cp, false)
}
func mapStrToNamespace(ns string, path string) (rspec.LinuxNamespace, error) {
@@ -1495,9 +1538,6 @@ func (g *Generator) AddDevice(device rspec.LinuxDevice) {
g.Config.Linux.Devices[i] = device
return
}
if dev.Type == device.Type && dev.Major == device.Major && dev.Minor == device.Minor {
fmt.Fprintln(os.Stderr, "WARNING: The same type, major and minor should not be used for multiple devices.")
}
}
g.Config.Linux.Devices = append(g.Config.Linux.Devices, device)
@@ -1556,12 +1596,8 @@ func (g *Generator) RemoveLinuxResourcesDevice(allow bool, devType string, major
return
}
}
return
}
// strPtr returns the pointer pointing to the string s.
func strPtr(s string) *string { return &s }
// SetSyscallAction adds rules for syscalls with the specified action
func (g *Generator) SetSyscallAction(arguments seccomp.SyscallOpts) error {
g.initConfigLinuxSeccomp()
@@ -1581,6 +1617,12 @@ func (g *Generator) SetDefaultSeccompActionForce(action string) error {
return seccomp.ParseDefaultActionForce(action, g.Config.Linux.Seccomp)
}
// SetDomainName sets g.Config.Domainname
func (g *Generator) SetDomainName(domain string) {
g.initConfig()
g.Config.Domainname = domain
}
// SetSeccompArchitecture sets the supported seccomp architectures
func (g *Generator) SetSeccompArchitecture(architecture string) error {
g.initConfigLinuxSeccomp()
@@ -1687,14 +1729,14 @@ func (g *Generator) SetVMHypervisorPath(path string) error {
if !strings.HasPrefix(path, "/") {
return fmt.Errorf("hypervisorPath %v is not an absolute path", path)
}
g.initConfigVMHypervisor()
g.initConfigVM()
g.Config.VM.Hypervisor.Path = path
return nil
}
// SetVMHypervisorParameters sets g.Config.VM.Hypervisor.Parameters
func (g *Generator) SetVMHypervisorParameters(parameters []string) {
g.initConfigVMHypervisor()
g.initConfigVM()
g.Config.VM.Hypervisor.Parameters = parameters
}
@@ -1703,14 +1745,14 @@ func (g *Generator) SetVMKernelPath(path string) error {
if !strings.HasPrefix(path, "/") {
return fmt.Errorf("kernelPath %v is not an absolute path", path)
}
g.initConfigVMKernel()
g.initConfigVM()
g.Config.VM.Kernel.Path = path
return nil
}
// SetVMKernelParameters sets g.Config.VM.Kernel.Parameters
func (g *Generator) SetVMKernelParameters(parameters []string) {
g.initConfigVMKernel()
g.initConfigVM()
g.Config.VM.Kernel.Parameters = parameters
}
@@ -1719,7 +1761,7 @@ func (g *Generator) SetVMKernelInitRD(initrd string) error {
if !strings.HasPrefix(initrd, "/") {
return fmt.Errorf("kernelInitrd %v is not an absolute path", initrd)
}
g.initConfigVMKernel()
g.initConfigVM()
g.Config.VM.Kernel.InitRD = initrd
return nil
}
@@ -1729,7 +1771,7 @@ func (g *Generator) SetVMImagePath(path string) error {
if !strings.HasPrefix(path, "/") {
return fmt.Errorf("imagePath %v is not an absolute path", path)
}
g.initConfigVMImage()
g.initConfigVM()
g.Config.VM.Image.Path = path
return nil
}
@@ -1745,7 +1787,7 @@ func (g *Generator) SetVMImageFormat(format string) error {
default:
return fmt.Errorf("Commonly supported formats are: raw, qcow2, vdi, vmdk, vhd")
}
g.initConfigVMImage()
g.initConfigVM()
g.Config.VM.Image.Format = format
return nil
}

View File

@@ -4,9 +4,4 @@ const (
seccompOverwrite = "overwrite"
seccompAppend = "append"
nothing = "nothing"
kill = "kill"
trap = "trap"
trace = "trace"
allow = "allow"
errno = "errno"
)

View File

@@ -151,6 +151,9 @@ func DefaultProfile(rs *specs.Spec) *rspec.LinuxSeccomp {
"io_submit",
"ipc",
"kill",
"landlock_add_rule",
"landlock_create_ruleset",
"landlock_restrict_self",
"lchown",
"lchown32",
"lgetxattr",
@@ -303,6 +306,7 @@ func DefaultProfile(rs *specs.Spec) *rspec.LinuxSeccomp {
"stat64",
"statfs",
"statfs64",
"statx",
"symlink",
"symlinkat",
"sync",
@@ -353,11 +357,23 @@ func DefaultProfile(rs *specs.Spec) *rspec.LinuxSeccomp {
Value: 0x0,
Op: rspec.OpEqualTo,
},
},
},
{
Names: []string{"personality"},
Action: rspec.ActAllow,
Args: []rspec.LinuxSeccompArg{
{
Index: 0,
Value: 0x0008,
Op: rspec.OpEqualTo,
},
},
},
{
Names: []string{"personality"},
Action: rspec.ActAllow,
Args: []rspec.LinuxSeccompArg{
{
Index: 0,
Value: 0xffffffff,
@@ -512,7 +528,7 @@ func DefaultProfile(rs *specs.Spec) *rspec.LinuxSeccomp {
Args: []rspec.LinuxSeccompArg{
{
Index: sysCloneFlagsIndex,
Value: CloneNewNS | CloneNewUTS | CloneNewIPC | CloneNewUser | CloneNewPID | CloneNewNet,
Value: CloneNewNS | CloneNewUTS | CloneNewIPC | CloneNewUser | CloneNewPID | CloneNewNet | CloneNewCgroup,
ValueTwo: 0,
Op: rspec.OpMaskedEqual,
},
@@ -566,6 +582,20 @@ func DefaultProfile(rs *specs.Spec) *rspec.LinuxSeccomp {
},
}...)
/* Flags parameter of the clone syscall is the 2nd on s390 */
syscalls = append(syscalls, []rspec.LinuxSyscall{
{
Names: []string{"clone"},
Action: rspec.ActAllow,
Args: []rspec.LinuxSeccompArg{
{
Index: 1,
Value: 2080505856,
ValueTwo: 0,
Op: rspec.OpMaskedEqual,
},
},
},
}...)
}
return &rspec.LinuxSeccomp{

View File

@@ -1,15 +1,17 @@
//go:build linux
// +build linux
package seccomp
import "syscall"
import "golang.org/x/sys/unix"
// System values passed through on linux
const (
CloneNewIPC = syscall.CLONE_NEWIPC
CloneNewNet = syscall.CLONE_NEWNET
CloneNewNS = syscall.CLONE_NEWNS
CloneNewPID = syscall.CLONE_NEWPID
CloneNewUser = syscall.CLONE_NEWUSER
CloneNewUTS = syscall.CLONE_NEWUTS
CloneNewIPC = unix.CLONE_NEWIPC
CloneNewNet = unix.CLONE_NEWNET
CloneNewNS = unix.CLONE_NEWNS
CloneNewPID = unix.CLONE_NEWPID
CloneNewUser = unix.CLONE_NEWUSER
CloneNewUTS = unix.CLONE_NEWUTS
CloneNewCgroup = unix.CLONE_NEWCGROUP
)

View File

@@ -1,3 +1,4 @@
//go:build !linux
// +build !linux
package seccomp

View File

@@ -92,22 +92,6 @@ func identical(config1, config2 *rspec.LinuxSyscall) bool {
return reflect.DeepEqual(config1, config2)
}
func identicalExceptAction(config1, config2 *rspec.LinuxSyscall) bool {
samename := sameName(config1, config2)
sameAction := sameAction(config1, config2)
sameArgs := sameArgs(config1, config2)
return samename && !sameAction && sameArgs
}
func identicalExceptArgs(config1, config2 *rspec.LinuxSyscall) bool {
samename := sameName(config1, config2)
sameAction := sameAction(config1, config2)
sameArgs := sameArgs(config1, config2)
return samename && sameAction && !sameArgs
}
func sameName(config1, config2 *rspec.LinuxSyscall) bool {
return reflect.DeepEqual(config1.Names, config2.Names)
}