config: Protect vhost_user_store_path against annotation attacks

This path could be used to overwrite data on the host.

Fixes: #901

Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
This commit is contained in:
Christophe de Dinechin 2020-05-15 18:42:30 +02:00 committed by Peng Tao
parent 8cd094cf06
commit c2a186b18c
7 changed files with 22 additions and 0 deletions

View File

@ -212,6 +212,9 @@ vhost_user_store_path = "@DEFVHOSTUSERSTOREPATH@"
# Enabling this will result in the VM device having iommu_platform=on set # Enabling this will result in the VM device having iommu_platform=on set
#enable_iommu_platform = true #enable_iommu_platform = true
# 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 # 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 # will disable this feature. In the case of virtio-fs, this is enabled
# automatically and '/dev/shm' is used as the backing folder. # automatically and '/dev/shm' is used as the backing folder.

View File

@ -217,6 +217,9 @@ vhost_user_store_path = "@DEFVHOSTUSERSTOREPATH@"
# Enabling this will result in the VM device having iommu_platform=on set # Enabling this will result in the VM device having iommu_platform=on set
#enable_iommu_platform = true #enable_iommu_platform = true
# 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 # 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 # will disable this feature. In the case of virtio-fs, this is enabled
# automatically and '/dev/shm' is used as the backing folder. # automatically and '/dev/shm' is used as the backing folder.

View File

@ -680,6 +680,7 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
DisableVhostNet: h.DisableVhostNet, DisableVhostNet: h.DisableVhostNet,
EnableVhostUserStore: h.EnableVhostUserStore, EnableVhostUserStore: h.EnableVhostUserStore,
VhostUserStorePath: h.vhostUserStorePath(), VhostUserStorePath: h.vhostUserStorePath(),
VhostUserStorePathList: h.VhostUserStorePathList,
GuestHookPath: h.guestHookPath(), GuestHookPath: h.guestHookPath(),
RxRateLimiterMaxRate: rxRateLimiterMaxRate, RxRateLimiterMaxRate: rxRateLimiterMaxRate,
TxRateLimiterMaxRate: txRateLimiterMaxRate, TxRateLimiterMaxRate: txRateLimiterMaxRate,

View File

@ -412,6 +412,9 @@ type HypervisorConfig struct {
// related folders, sockets and device nodes should be. // related folders, sockets and device nodes should be.
VhostUserStorePath string 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 is the path within the VM that will be used for 'drop-in' hooks
GuestHookPath string GuestHookPath string

View File

@ -247,6 +247,7 @@ func (s *Sandbox) dumpConfig(ss *persistapi.SandboxState) {
DisableVhostNet: sconfig.HypervisorConfig.DisableVhostNet, DisableVhostNet: sconfig.HypervisorConfig.DisableVhostNet,
EnableVhostUserStore: sconfig.HypervisorConfig.EnableVhostUserStore, EnableVhostUserStore: sconfig.HypervisorConfig.EnableVhostUserStore,
VhostUserStorePath: sconfig.HypervisorConfig.VhostUserStorePath, VhostUserStorePath: sconfig.HypervisorConfig.VhostUserStorePath,
VhostUserStorePathList: sconfig.HypervisorConfig.VhostUserStorePathList,
GuestHookPath: sconfig.HypervisorConfig.GuestHookPath, GuestHookPath: sconfig.HypervisorConfig.GuestHookPath,
VMid: sconfig.HypervisorConfig.VMid, VMid: sconfig.HypervisorConfig.VMid,
RxRateLimiterMaxRate: sconfig.HypervisorConfig.RxRateLimiterMaxRate, RxRateLimiterMaxRate: sconfig.HypervisorConfig.RxRateLimiterMaxRate,
@ -512,6 +513,7 @@ func loadSandboxConfig(id string) (*SandboxConfig, error) {
DisableVhostNet: hconf.DisableVhostNet, DisableVhostNet: hconf.DisableVhostNet,
EnableVhostUserStore: hconf.EnableVhostUserStore, EnableVhostUserStore: hconf.EnableVhostUserStore,
VhostUserStorePath: hconf.VhostUserStorePath, VhostUserStorePath: hconf.VhostUserStorePath,
VhostUserStorePathList: hconf.VhostUserStorePathList,
GuestHookPath: hconf.GuestHookPath, GuestHookPath: hconf.GuestHookPath,
VMid: hconf.VMid, VMid: hconf.VMid,
RxRateLimiterMaxRate: hconf.RxRateLimiterMaxRate, RxRateLimiterMaxRate: hconf.RxRateLimiterMaxRate,

View File

@ -186,6 +186,9 @@ type HypervisorConfig struct {
// related folders, sockets and device nodes should be. // related folders, sockets and device nodes should be.
VhostUserStorePath string 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 is the path within the VM that will be used for 'drop-in' hooks
GuestHookPath string GuestHookPath string

View File

@ -434,6 +434,13 @@ func addHypervisorConfigOverrides(ocispec specs.Spec, config *vc.SandboxConfig,
} }
} }
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, ok := ocispec.Annotations[vcAnnotations.GuestHookPath]; ok {
if value != "" { if value != "" {
config.HypervisorConfig.GuestHookPath = value config.HypervisorConfig.GuestHookPath = value