From 33021ef28ea5f7e09dd50bf6516f7040ccdb1490 Mon Sep 17 00:00:00 2001 From: Christophe de Dinechin Date: Tue, 19 May 2020 19:19:42 +0200 Subject: [PATCH] config: Whitelist hypervisor annotations by name Add a field "enable_annotations" to the runtime configuration that can be used to whitelist annotations using a list of regular expressions, which are used to match any part of the base annotation name, i.e. the part after "io.katacontainers.config.hypervisor." For example, the following configuraiton will match "virtio_fs_daemon", "initrd" and "jailer_path", but not "path" nor "firmware": enable_annotations = [ "virtio.*", "initrd", "_path" ] The default is an empty list of enabled annotations, which disables annotations entirely. If an anontation is rejected, the message is something like: annotation io.katacontainers.config.hypervisor.virtio_fs_daemon is not enabled Fixes: #3004 Suggested-by: Peng Tao Signed-off-by: Christophe de Dinechin --- Makefile | 2 ++ cli/config/configuration-acrn.toml.in | 5 +++++ cli/config/configuration-clh.toml.in | 5 +++++ cli/config/configuration-fc.toml.in | 5 +++++ cli/config/configuration-qemu-virtiofs.toml.in | 5 +++++ cli/config/configuration-qemu.toml.in | 5 +++++ pkg/katautils/config.go | 5 +++++ virtcontainers/hypervisor.go | 3 +++ virtcontainers/persist.go | 2 ++ virtcontainers/persist/api/config.go | 3 +++ virtcontainers/pkg/annotations/annotations.go | 1 + virtcontainers/pkg/oci/utils.go | 14 +++++++++++++- 12 files changed, 54 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7969d51b9c..1e40be6903 100644 --- a/Makefile +++ b/Makefile @@ -169,6 +169,7 @@ DEFMEMSZ := 2048 DEFMEMSLOTS := 10 #Default number of bridges DEFBRIDGES := 1 +DEFENABLEANNOTATIONS := [] DEFDISABLEGUESTSECCOMP := true #Default experimental features enabled DEFAULTEXPFEATURES := [] @@ -664,6 +665,7 @@ $(GENERATED_FILES): %: %.in $(MAKEFILE_LIST) VERSION .git-commit -e "s|@DEFNETWORKMODEL_CLH@|$(DEFNETWORKMODEL_CLH)|g" \ -e "s|@DEFNETWORKMODEL_FC@|$(DEFNETWORKMODEL_FC)|g" \ -e "s|@DEFNETWORKMODEL_QEMU@|$(DEFNETWORKMODEL_QEMU)|g" \ + -e "s|@DEFENABLEANNOTATIONS@|$(DEFENABLEANNOTATIONS)|g" \ -e "s|@DEFDISABLEGUESTSECCOMP@|$(DEFDISABLEGUESTSECCOMP)|g" \ -e "s|@DEFAULTEXPFEATURES@|$(DEFAULTEXPFEATURES)|g" \ -e "s|@DEFDISABLEBLOCK@|$(DEFDISABLEBLOCK)|g" \ diff --git a/cli/config/configuration-acrn.toml.in b/cli/config/configuration-acrn.toml.in index c7deb4ee19..3064285a71 100644 --- a/cli/config/configuration-acrn.toml.in +++ b/cli/config/configuration-acrn.toml.in @@ -16,6 +16,11 @@ ctlpath = "@ACRNCTLPATH@" kernel = "@KERNELPATH_ACRN@" image = "@IMAGEPATH@" +# List of valid annotation names for the hypervisor +# Each member of the list is a regular expression, which is the base name +# of the annotation, e.g. "path" for io.katacontainers.config.hypervisor.path" +enable_annotations = @DEFENABLEANNOTATIONS@ + # List of valid annotations values for the hypervisor (default: empty) # Each member of the list is a path pattern as described by glob(3). path_list = @ACRNPATHLIST@ diff --git a/cli/config/configuration-clh.toml.in b/cli/config/configuration-clh.toml.in index 820dd29718..2e5aa0381a 100644 --- a/cli/config/configuration-clh.toml.in +++ b/cli/config/configuration-clh.toml.in @@ -15,6 +15,11 @@ path = "@CLHPATH@" kernel = "@KERNELPATH_CLH@" image = "@IMAGEPATH@" +# List of valid annotation names for the hypervisor +# Each member of the list is a regular expression, which is the base name +# of the annotation, e.g. "path" for io.katacontainers.config.hypervisor.path" +enable_annotations = @DEFENABLEANNOTATIONS@ + # List of valid annotations values for the hypervisor (default: empty) # Each member of the list is a path pattern as described by glob(3). path_list = @CLHPATHLIST@ diff --git a/cli/config/configuration-fc.toml.in b/cli/config/configuration-fc.toml.in index 743cecdea1..26f9c8b4a3 100644 --- a/cli/config/configuration-fc.toml.in +++ b/cli/config/configuration-fc.toml.in @@ -15,6 +15,11 @@ path = "@FCPATH@" kernel = "@KERNELPATH_FC@" image = "@IMAGEPATH@" +# List of valid annotation names for the hypervisor +# Each member of the list is a regular expression, which is the base name +# of the annotation, e.g. "path" for io.katacontainers.config.hypervisor.path" +enable_annotations = @DEFENABLEANNOTATIONS@ + # List of valid annotations values for the hypervisor (default: empty) # Each member of the list is a path pattern as described by glob(3). path_list = @FCPATHLIST@ diff --git a/cli/config/configuration-qemu-virtiofs.toml.in b/cli/config/configuration-qemu-virtiofs.toml.in index c2773cdfaf..74af32ad71 100644 --- a/cli/config/configuration-qemu-virtiofs.toml.in +++ b/cli/config/configuration-qemu-virtiofs.toml.in @@ -16,6 +16,11 @@ kernel = "@KERNELVIRTIOFSPATH@" image = "@IMAGEPATH@" machine_type = "@MACHINETYPE@" +# List of valid annotation names for the hypervisor +# Each member of the list is a regular expression, which is the base name +# of the annotation, e.g. "path" for io.katacontainers.config.hypervisor.path" +enable_annotations = @DEFENABLEANNOTATIONS@ + # List of valid annotations values for the hypervisor (default: empty) # Each member of the list is a path pattern as described by glob(3). path_list = @QEMUVIRTIOFSPATHLIST@ diff --git a/cli/config/configuration-qemu.toml.in b/cli/config/configuration-qemu.toml.in index db591ecfc4..f09fcd942b 100644 --- a/cli/config/configuration-qemu.toml.in +++ b/cli/config/configuration-qemu.toml.in @@ -17,6 +17,11 @@ initrd = "@INITRDPATH@" image = "@IMAGEPATH@" machine_type = "@MACHINETYPE@" +# List of valid annotation names for the hypervisor +# Each member of the list is a regular expression, which is the base name +# of the annotation, e.g. "path" for io.katacontainers.config.hypervisor.path" +enable_annotations = @DEFENABLEANNOTATIONS@ + # List of valid annotations values for the hypervisor (default: empty) # Each member of the list is a path pattern as described by glob(3). path_list = @QEMUPATHLIST@ diff --git a/pkg/katautils/config.go b/pkg/katautils/config.go index e05094f04c..43022dc415 100644 --- a/pkg/katautils/config.go +++ b/pkg/katautils/config.go @@ -134,6 +134,7 @@ type hypervisor struct { HotplugVFIOOnRootBus bool `toml:"hotplug_vfio_on_root_bus"` DisableVhostNet bool `toml:"disable_vhost_net"` GuestHookPath string `toml:"guest_hook_path"` + EnableAnnotations []string `toml:"enable_annotations"` } type proxy struct { @@ -565,6 +566,7 @@ func newFirecrackerHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { DisableVhostNet: true, // vhost-net backend is not supported in Firecracker UseVSock: true, GuestHookPath: h.guestHookPath(), + EnableAnnotations: h.EnableAnnotations, }, nil } @@ -675,6 +677,7 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { VhostUserStorePath: h.vhostUserStorePath(), VhostUserStorePathList: h.VhostUserStorePathList, GuestHookPath: h.guestHookPath(), + EnableAnnotations: h.EnableAnnotations, }, nil } @@ -738,6 +741,7 @@ func newAcrnHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { BlockDeviceDriver: blockDriver, DisableVhostNet: h.DisableVhostNet, GuestHookPath: h.guestHookPath(), + EnableAnnotations: h.EnableAnnotations, }, nil } @@ -829,6 +833,7 @@ func newClhHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { PCIeRootPort: h.PCIeRootPort, DisableVhostNet: true, UseVSock: true, + EnableAnnotations: h.EnableAnnotations, }, nil } diff --git a/virtcontainers/hypervisor.go b/virtcontainers/hypervisor.go index 5c15f582d2..8bc26a6da1 100644 --- a/virtcontainers/hypervisor.go +++ b/virtcontainers/hypervisor.go @@ -424,6 +424,9 @@ type HypervisorConfig struct { // SELinux label for the VM SELinuxProcessLabel string + + // Enable annotations by name + EnableAnnotations []string } // vcpu mapping from vcpu number to thread number diff --git a/virtcontainers/persist.go b/virtcontainers/persist.go index ed07d3b09c..f0f5a2029c 100644 --- a/virtcontainers/persist.go +++ b/virtcontainers/persist.go @@ -262,6 +262,7 @@ func (s *Sandbox) dumpConfig(ss *persistapi.SandboxState) { VhostUserStorePathList: sconfig.HypervisorConfig.VhostUserStorePathList, GuestHookPath: sconfig.HypervisorConfig.GuestHookPath, VMid: sconfig.HypervisorConfig.VMid, + EnableAnnotations: sconfig.HypervisorConfig.EnableAnnotations, } if sconfig.AgentType == "kata" { @@ -557,6 +558,7 @@ func loadSandboxConfig(id string) (*SandboxConfig, error) { VhostUserStorePathList: hconf.VhostUserStorePathList, GuestHookPath: hconf.GuestHookPath, VMid: hconf.VMid, + EnableAnnotations: hconf.EnableAnnotations, } if savedConf.AgentType == "kata" { diff --git a/virtcontainers/persist/api/config.go b/virtcontainers/persist/api/config.go index 27de219899..1820babc3c 100644 --- a/virtcontainers/persist/api/config.go +++ b/virtcontainers/persist/api/config.go @@ -198,6 +198,9 @@ type HypervisorConfig struct { // VMid is the id of the VM that create the hypervisor if the VM is created by the factory. // VMid is "" if the hypervisor is not created by the factory. VMid string + + // Enable annotations by name + EnableAnnotations []string } // KataAgentConfig is a structure storing information needed diff --git a/virtcontainers/pkg/annotations/annotations.go b/virtcontainers/pkg/annotations/annotations.go index 310ea71a7b..a78614f11d 100644 --- a/virtcontainers/pkg/annotations/annotations.go +++ b/virtcontainers/pkg/annotations/annotations.go @@ -28,6 +28,7 @@ const ( // // Assets // + KataAnnotationHypervisorPrefix = kataAnnotHypervisorPrefix // KernelPath is a sandbox annotation for passing a per container path pointing at the kernel needed to boot the container VM. KernelPath = kataAnnotHypervisorPrefix + "kernel" diff --git a/virtcontainers/pkg/oci/utils.go b/virtcontainers/pkg/oci/utils.go index de21b72c90..a9979db8ad 100644 --- a/virtcontainers/pkg/oci/utils.go +++ b/virtcontainers/pkg/oci/utils.go @@ -224,6 +224,14 @@ func checkPathIsInGlobList(list []string, path string) bool { return false } +// Check if an annotation name either belongs to another prefix, matches regexp list +func checkAnnotationNameIsValid(list []string, name string, prefix string) bool { + if strings.HasPrefix(name, prefix) { + return regexpContains(list, strings.TrimPrefix(name, prefix)) + } + return true +} + func newLinuxDeviceInfo(d specs.LinuxDevice) (*config.DeviceInfo, error) { allowedDeviceTypes := []string{"c", "b", "u", "p"} @@ -357,11 +365,15 @@ func SandboxID(spec specs.Spec) (string, error) { } func addAnnotations(ocispec specs.Spec, config *vc.SandboxConfig, runtime RuntimeConfig) error { + for key := range ocispec.Annotations { + if !checkAnnotationNameIsValid(runtime.HypervisorConfig.EnableAnnotations, key, vcAnnotations.KataAnnotationHypervisorPrefix) { + return fmt.Errorf("annotation %v is not enabled", key) + } + } err := addAssetAnnotations(ocispec, config) if err != nil { return err } - if err := addHypervisorConfigOverrides(ocispec, config, runtime); err != nil { return err }