From 88b0544ede0c6e31febd40fa69653260de9530b1 Mon Sep 17 00:00:00 2001 From: Christophe de Dinechin Date: Fri, 15 May 2020 18:42:30 +0200 Subject: [PATCH] config: Protect vhost_user_store_path against annotation attacks This path could be used to overwrite data on the host. Fixes: #3004 Signed-off-by: Christophe de Dinechin --- cli/config/configuration-qemu-virtiofs.toml.in | 3 +++ cli/config/configuration-qemu.toml.in | 3 +++ pkg/katautils/config.go | 1 + virtcontainers/hypervisor.go | 3 +++ virtcontainers/persist.go | 2 ++ virtcontainers/persist/api/config.go | 3 +++ virtcontainers/pkg/oci/utils.go | 7 +++++++ 7 files changed, 22 insertions(+) diff --git a/cli/config/configuration-qemu-virtiofs.toml.in b/cli/config/configuration-qemu-virtiofs.toml.in index de9887e8e4..66fc72fa77 100644 --- a/cli/config/configuration-qemu-virtiofs.toml.in +++ b/cli/config/configuration-qemu-virtiofs.toml.in @@ -196,6 +196,9 @@ enable_vhost_user_store = @DEFENABLEVHOSTUSERSTORE@ # simulated block device nodes for vhost-user devices to live. vhost_user_store_path = "@DEFVHOSTUSERSTOREPATH@" +# List of valid annotations values for the virtiofs daemon (default: empty) +# vhost_user_store_path_list = [ "/empty/space", "/multiverse/quantum-foam" ] + # Enable file based guest memory support. The default is an empty string which # will disable this feature. In the case of virtio-fs, this is enabled # automatically and '/dev/shm' is used as the backing folder. diff --git a/cli/config/configuration-qemu.toml.in b/cli/config/configuration-qemu.toml.in index d6c86ec775..f447430227 100644 --- a/cli/config/configuration-qemu.toml.in +++ b/cli/config/configuration-qemu.toml.in @@ -202,6 +202,9 @@ enable_vhost_user_store = @DEFENABLEVHOSTUSERSTORE@ # simulated block device nodes for vhost-user devices to live. vhost_user_store_path = "@DEFVHOSTUSERSTOREPATH@" +# List of valid annotations values for the virtiofs daemon (default: empty) +# vhost_user_store_path_list = [ "/empty/space", "/multiverse/quantum-foam" ] + # Enable file based guest memory support. The default is an empty string which # will disable this feature. In the case of virtio-fs, this is enabled # automatically and '/dev/shm' is used as the backing folder. diff --git a/pkg/katautils/config.go b/pkg/katautils/config.go index 498d564511..74cc0ce0b7 100644 --- a/pkg/katautils/config.go +++ b/pkg/katautils/config.go @@ -672,6 +672,7 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { DisableVhostNet: h.DisableVhostNet, EnableVhostUserStore: h.EnableVhostUserStore, VhostUserStorePath: h.vhostUserStorePath(), + VhostUserStorePathList: h.VhostUserStorePathList, GuestHookPath: h.guestHookPath(), }, nil } diff --git a/virtcontainers/hypervisor.go b/virtcontainers/hypervisor.go index 95b2324444..a71b0e95aa 100644 --- a/virtcontainers/hypervisor.go +++ b/virtcontainers/hypervisor.go @@ -409,6 +409,9 @@ type HypervisorConfig struct { // related folders, sockets and device nodes should be. VhostUserStorePath string + // VhostUserStorePathList is the list of valid values for vhost-user paths + VhostUserStorePathList []string + // GuestHookPath is the path within the VM that will be used for 'drop-in' hooks GuestHookPath string diff --git a/virtcontainers/persist.go b/virtcontainers/persist.go index 7b87289c9b..2ca7656fdf 100644 --- a/virtcontainers/persist.go +++ b/virtcontainers/persist.go @@ -258,6 +258,7 @@ func (s *Sandbox) dumpConfig(ss *persistapi.SandboxState) { DisableVhostNet: sconfig.HypervisorConfig.DisableVhostNet, EnableVhostUserStore: sconfig.HypervisorConfig.EnableVhostUserStore, VhostUserStorePath: sconfig.HypervisorConfig.VhostUserStorePath, + VhostUserStorePathList: sconfig.HypervisorConfig.VhostUserStorePathList, GuestHookPath: sconfig.HypervisorConfig.GuestHookPath, VMid: sconfig.HypervisorConfig.VMid, } @@ -551,6 +552,7 @@ func loadSandboxConfig(id string) (*SandboxConfig, error) { DisableVhostNet: hconf.DisableVhostNet, EnableVhostUserStore: hconf.EnableVhostUserStore, VhostUserStorePath: hconf.VhostUserStorePath, + VhostUserStorePathList: hconf.VhostUserStorePathList, GuestHookPath: hconf.GuestHookPath, VMid: hconf.VMid, } diff --git a/virtcontainers/persist/api/config.go b/virtcontainers/persist/api/config.go index 2d126ddbc0..147282f07f 100644 --- a/virtcontainers/persist/api/config.go +++ b/virtcontainers/persist/api/config.go @@ -186,6 +186,9 @@ type HypervisorConfig struct { // related folders, sockets and device nodes should be. VhostUserStorePath string + // VhostUserStorePathList is the list of valid values for vhost-user paths + VhostUserStorePathList []string + // GuestHookPath is the path within the VM that will be used for 'drop-in' hooks GuestHookPath string diff --git a/virtcontainers/pkg/oci/utils.go b/virtcontainers/pkg/oci/utils.go index 504cca315d..e45c165296 100644 --- a/virtcontainers/pkg/oci/utils.go +++ b/virtcontainers/pkg/oci/utils.go @@ -450,6 +450,13 @@ func addHypervisorConfigOverrides(ocispec specs.Spec, config *vc.SandboxConfig, config.HypervisorConfig.DisableVhostNet = disableVhostNet } + if value, ok := ocispec.Annotations[vcAnnotations.VhostUserStorePath]; ok { + if !regexpContains(runtime.HypervisorConfig.VhostUserStorePathList, value) { + return fmt.Errorf("vhost store path %v required from annotation is not valid", value) + } + config.HypervisorConfig.VhostUserStorePath = value + } + if value, ok := ocispec.Annotations[vcAnnotations.GuestHookPath]; ok { if value != "" { config.HypervisorConfig.GuestHookPath = value