diff --git a/Config.mk b/Config.mk index 79029a0be9..63ae38c7b6 100644 --- a/Config.mk +++ b/Config.mk @@ -150,9 +150,9 @@ QEMU_REMOTE=http://xenbits.xensource.com/git-http/qemu-xen-unstable.git # CONFIG_QEMU ?= ../qemu-xen.git CONFIG_QEMU ?= $(QEMU_REMOTE) -QEMU_TAG ?= a3285ff385d2568f0226f15fee2b9808ec3b6deb -# Tue Oct 20 15:16:34 2009 +0100 -# usb hotplug in qemu-dm via xm +QEMU_TAG ?= b4bb8b3f09d1c873f522f6aebe1f125a6d1854d0 +# Wed Oct 21 16:42:15 2009 +0100 +# passthrough: fix security issue with stubdoms OCAML_XENSTORED_REPO=http://xenbits.xensource.com/ext/xen-ocaml-tools.hg diff --git a/tools/python/xen/xend/server/pciif.py b/tools/python/xen/xend/server/pciif.py index 0e54ae14df..06b2ec9310 100644 --- a/tools/python/xen/xend/server/pciif.py +++ b/tools/python/xen/xend/server/pciif.py @@ -444,7 +444,15 @@ class PciController(DevController): # For hvm guest, (from c/s 19679 on) assigning device statically and # dynamically both go through reconfigureDevice(), so HERE the # setupOneDevice() is not necessary. - if not self.vm.info.is_hvm(): + if self.vm.info.is_hvm(): + for pci_dev in pci_dev_list: + # Setup IOMMU device assignment + bdf = xc.assign_device(self.getDomid(), pci_dict_to_xc_str(pci_dev)) + pci_str = pci_dict_to_bdf_str(pci_dev) + if bdf > 0: + raise VmError("Failed to assign device to IOMMU (%s)" % pci_str) + log.debug("pci: assign device %s" % pci_str) + else : for d in pci_dev_list: self.setupOneDevice(d) wPath = '/local/domain/0/backend/pci/%u/0/aerState' % (self.getDomid()) diff --git a/xen/Rules.mk b/xen/Rules.mk index 731e0cc88c..10847182ae 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -11,9 +11,6 @@ crash_debug ?= n gdbsx ?= n frame_pointer ?= n -# Allow some delicate passthrough related hypercalls to be made from a stubdom -privileged_stubdoms ?= y - XEN_ROOT=$(BASEDIR)/.. include $(XEN_ROOT)/Config.mk @@ -56,7 +53,6 @@ CFLAGS-$(perfc) += -DPERF_COUNTERS CFLAGS-$(perfc_arrays) += -DPERF_ARRAYS CFLAGS-$(lock_profile) += -DLOCK_PROFILE CFLAGS-$(frame_pointer) += -fno-omit-frame-pointer -DCONFIG_FRAME_POINTER -CFLAGS-$(privileged_stubdoms) += -DPRIVILEGED_STUBDOMS CFLAGS-$(gdbsx) += -DXEN_GDBSX_CONFIG ifneq ($(max_phys_cpus),) diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 581fcb3295..52f3945f06 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -796,6 +796,11 @@ long arch_do_domctl( if ( ret ) goto bind_out; + ret = -EPERM; + if ( !IS_PRIV(current->domain) && + !irq_access_permitted(current->domain, bind->machine_irq) ) + goto bind_out; + ret = -ESRCH; if ( iommu_enabled ) { @@ -820,6 +825,12 @@ long arch_do_domctl( if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL ) break; bind = &(domctl->u.bind_pt_irq); + + ret = -EPERM; + if ( !IS_PRIV(current->domain) && + !irq_access_permitted(current->domain, bind->machine_irq) ) + goto bind_out; + if ( iommu_enabled ) { spin_lock(&pcidevs_lock); @@ -848,6 +859,11 @@ long arch_do_domctl( if ( unlikely((d = rcu_lock_domain_by_id(domctl->domain)) == NULL) ) break; + ret = -EPERM; + if ( !IS_PRIV(current->domain) && + !iomem_access_permitted(current->domain, mfn, mfn + nr_mfns - 1) ) + break; + ret=0; if ( domctl->u.memory_mapping.add_mapping ) { @@ -895,6 +911,11 @@ long arch_do_domctl( break; } + ret = -EPERM; + if ( !IS_PRIV(current->domain) && + !ioports_access_permitted(current->domain, fmp, fmp + np - 1) ) + break; + ret = -ESRCH; if ( unlikely((d = rcu_lock_domain_by_id(domctl->domain)) == NULL) ) break; diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 510be8db12..74d096f462 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1343,7 +1343,9 @@ int map_domain_pirq( ASSERT(spin_is_locked(&pcidevs_lock)); ASSERT(spin_is_locked(&d->event_lock)); - if ( !STUBDOM_IS_PRIV_FOR(current->domain, d) ) + if ( !IS_PRIV(current->domain) && + !(IS_PRIV_FOR(current->domain, d) && + irq_access_permitted(current->domain, pirq))) return -EPERM; if ( pirq < 0 || pirq >= d->nr_pirqs || irq < 0 || irq >= nr_irqs ) diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c index 0c284e84bc..2d65fa4df4 100644 --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -45,7 +45,7 @@ static int physdev_map_pirq(struct physdev_map_pirq *map) if ( d == NULL ) return -ESRCH; - if ( !STUBDOM_IS_PRIV_FOR(current->domain, d) ) + if ( !IS_PRIV_FOR(current->domain, d) ) { ret = -EPERM; goto free_domain; @@ -169,7 +169,7 @@ static int physdev_unmap_pirq(struct physdev_unmap_pirq *unmap) return -ESRCH; ret = -EPERM; - if ( !STUBDOM_IS_PRIV_FOR(current->domain, d) ) + if ( !IS_PRIV_FOR(current->domain, d) ) goto free_domain; spin_lock(&pcidevs_lock); diff --git a/xen/common/domctl.c b/xen/common/domctl.c index 0b9ad758dd..290b9494dd 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -231,14 +231,12 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) case XEN_DOMCTL_ioport_mapping: case XEN_DOMCTL_memory_mapping: case XEN_DOMCTL_bind_pt_irq: - case XEN_DOMCTL_unbind_pt_irq: - case XEN_DOMCTL_assign_device: - case XEN_DOMCTL_deassign_device: { + case XEN_DOMCTL_unbind_pt_irq: { struct domain *d; bool_t is_priv = IS_PRIV(current->domain); if ( !is_priv && ((d = rcu_lock_domain_by_id(op->domain)) != NULL) ) { - is_priv = STUBDOM_IS_PRIV_FOR(current->domain, d); + is_priv = IS_PRIV_FOR(current->domain, d); rcu_unlock_domain(d); } if ( !is_priv ) diff --git a/xen/include/xen/config.h b/xen/include/xen/config.h index 43d6bc6cff..7872f13e8d 100644 --- a/xen/include/xen/config.h +++ b/xen/include/xen/config.h @@ -95,10 +95,4 @@ int current_domain_id(void); #define __cpuinitdata #define __cpuinit -#ifdef PRIVILEGED_STUBDOMS -#define STUBDOM_IS_PRIV_FOR(x,y) IS_PRIV_FOR(x,y) -#else -#define STUBDOM_IS_PRIV_FOR(x,y) IS_PRIV(x) -#endif - #endif /* __XEN_CONFIG_H__ */