From 4e89b885d25e5701c068b1c9e76d35fd05e20919 Mon Sep 17 00:00:00 2001 From: Christophe de Dinechin Date: Fri, 15 May 2020 18:55:02 +0200 Subject: [PATCH] config: Protect file_mem_backend against annotation attacks This one could theoretically be used to overwrite data on the host. It seems somewhat less risky than the earlier ones for a number of reasons, but worth protecting a little anyway. Fixes: #901 Signed-off-by: Christophe de Dinechin --- src/runtime/cli/config/configuration-qemu-virtiofs.toml.in | 3 +++ src/runtime/cli/config/configuration-qemu.toml.in | 3 +++ src/runtime/pkg/katautils/config.go | 2 ++ src/runtime/virtcontainers/hypervisor.go | 3 +++ src/runtime/virtcontainers/persist.go | 2 ++ src/runtime/virtcontainers/persist/api/config.go | 3 +++ src/runtime/virtcontainers/pkg/oci/utils.go | 7 +++++-- 7 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/runtime/cli/config/configuration-qemu-virtiofs.toml.in b/src/runtime/cli/config/configuration-qemu-virtiofs.toml.in index 6ec254fe55..d9564adfb3 100644 --- a/src/runtime/cli/config/configuration-qemu-virtiofs.toml.in +++ b/src/runtime/cli/config/configuration-qemu-virtiofs.toml.in @@ -221,6 +221,9 @@ vhost_user_store_path = "@DEFVHOSTUSERSTOREPATH@" # This option will be ignored if VM templating is enabled. #file_mem_backend = "" +# List of valid annotations values for the file_mem_backend annotation (default: empty) +# file_mem_backend_list = [ "/dev/shm" ] + # Enable swap of vm memory. Default false. # The behaviour is undefined if mem_prealloc is also set to true #enable_swap = true diff --git a/src/runtime/cli/config/configuration-qemu.toml.in b/src/runtime/cli/config/configuration-qemu.toml.in index d1f63f7e7f..e87daa107e 100644 --- a/src/runtime/cli/config/configuration-qemu.toml.in +++ b/src/runtime/cli/config/configuration-qemu.toml.in @@ -226,6 +226,9 @@ vhost_user_store_path = "@DEFVHOSTUSERSTOREPATH@" # This option will be ignored if VM templating is enabled. #file_mem_backend = "" +# List of valid annotations values for the file_mem_backend annotation (default: empty) +# file_mem_backend_list = [ "/dev/shm" ] + # Enable swap of vm memory. Default false. # The behaviour is undefined if mem_prealloc is also set to true #enable_swap = true diff --git a/src/runtime/pkg/katautils/config.go b/src/runtime/pkg/katautils/config.go index 1ce463417f..d266bd55fd 100644 --- a/src/runtime/pkg/katautils/config.go +++ b/src/runtime/pkg/katautils/config.go @@ -665,6 +665,7 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { IOMMU: h.IOMMU, IOMMUPlatform: h.getIOMMUPlatform(), FileBackedMemRootDir: h.FileBackedMemRootDir, + FileBackedMemRootList: h.FileBackedMemRootList, Mlock: !h.Swap, Debug: h.Debug, DisableNestingChecks: h.DisableNestingChecks, @@ -824,6 +825,7 @@ func newClhHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { MemPrealloc: h.MemPrealloc, HugePages: h.HugePages, FileBackedMemRootDir: h.FileBackedMemRootDir, + FileBackedMemRootList: h.FileBackedMemRootList, Mlock: !h.Swap, Debug: h.Debug, DisableNestingChecks: h.DisableNestingChecks, diff --git a/src/runtime/virtcontainers/hypervisor.go b/src/runtime/virtcontainers/hypervisor.go index 2f43f699df..46fac8907d 100644 --- a/src/runtime/virtcontainers/hypervisor.go +++ b/src/runtime/virtcontainers/hypervisor.go @@ -330,6 +330,9 @@ type HypervisorConfig struct { // File based memory backend root directory FileBackedMemRootDir string + // FileBackedMemRootList is the list of valid root directories values for annotations + FileBackedMemRootList []string + // customAssets is a map of assets. // Each value in that map takes precedence over the configured assets. // For example, if there is a value for the "kernel" key in this map, diff --git a/src/runtime/virtcontainers/persist.go b/src/runtime/virtcontainers/persist.go index cdb90cb8d0..65399e86af 100644 --- a/src/runtime/virtcontainers/persist.go +++ b/src/runtime/virtcontainers/persist.go @@ -236,6 +236,7 @@ func (s *Sandbox) dumpConfig(ss *persistapi.SandboxState) { MemPrealloc: sconfig.HypervisorConfig.MemPrealloc, HugePages: sconfig.HypervisorConfig.HugePages, FileBackedMemRootDir: sconfig.HypervisorConfig.FileBackedMemRootDir, + FileBackedMemRootList: sconfig.HypervisorConfig.FileBackedMemRootList, Realtime: sconfig.HypervisorConfig.Realtime, Mlock: sconfig.HypervisorConfig.Mlock, DisableNestingChecks: sconfig.HypervisorConfig.DisableNestingChecks, @@ -503,6 +504,7 @@ func loadSandboxConfig(id string) (*SandboxConfig, error) { MemPrealloc: hconf.MemPrealloc, HugePages: hconf.HugePages, FileBackedMemRootDir: hconf.FileBackedMemRootDir, + FileBackedMemRootList: hconf.FileBackedMemRootList, Realtime: hconf.Realtime, Mlock: hconf.Mlock, DisableNestingChecks: hconf.DisableNestingChecks, diff --git a/src/runtime/virtcontainers/persist/api/config.go b/src/runtime/virtcontainers/persist/api/config.go index 10fee16395..025c93d1a9 100644 --- a/src/runtime/virtcontainers/persist/api/config.go +++ b/src/runtime/virtcontainers/persist/api/config.go @@ -116,6 +116,9 @@ type HypervisorConfig struct { // File based memory backend root directory FileBackedMemRootDir string + // FileBackedMemRootList is the list of valid root directories values for annotations + FileBackedMemRootList []string + // BlockDeviceCacheSet specifies cache-related options will be set to block devices or not. BlockDeviceCacheSet bool diff --git a/src/runtime/virtcontainers/pkg/oci/utils.go b/src/runtime/virtcontainers/pkg/oci/utils.go index 6a14c39dd3..2053d4d403 100644 --- a/src/runtime/virtcontainers/pkg/oci/utils.go +++ b/src/runtime/virtcontainers/pkg/oci/utils.go @@ -375,7 +375,7 @@ func addHypervisorConfigOverrides(ocispec specs.Spec, config *vc.SandboxConfig, return err } - if err := addHypervisorMemoryOverrides(ocispec, config); err != nil { + if err := addHypervisorMemoryOverrides(ocispec, config, runtime); err != nil { return err } @@ -497,7 +497,7 @@ func addHypervisorConfigOverrides(ocispec specs.Spec, config *vc.SandboxConfig, return nil } -func addHypervisorMemoryOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConfig) error { +func addHypervisorMemoryOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConfig, runtime RuntimeConfig) error { if value, ok := ocispec.Annotations[vcAnnotations.DefaultMemory]; ok { memorySz, err := strconv.ParseUint(value, 10, 32) if err != nil { @@ -561,6 +561,9 @@ func addHypervisorMemoryOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConfig } if value, ok := ocispec.Annotations[vcAnnotations.FileBackedMemRootDir]; ok { + if !regexpContains(runtime.HypervisorConfig.FileBackedMemRootList, value) { + return fmt.Errorf("file_mem_backend value %v required from annotation is not valid", value) + } sbConfig.HypervisorConfig.FileBackedMemRootDir = value }