untrusted comment: verify with openbsd-66-base.pub RWSvK/c+cFe24AxipdqCUWAjUtIAO0sKPUESnkKS/ap3EnoVDEVbk8Oq8ym/c/M423lIak4AQbJOHeJaMaDAfzhQM7ns06BHNww= OpenBSD 6.6 errata 020, February 17, 2020: A missing range check in the vmm pvclock allows a guest to write to host memory. Apply by doing: signify -Vep /etc/signify/openbsd-66-base.pub -x 020_vmm_pvclock.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install a new kernel: KK=`sysctl -n kern.osversion | cut -d# -f1` cd /usr/src/sys/arch/`machine`/compile/$KK make obj make config make make install Index: sys/arch/amd64/amd64/vmm.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/vmm.c,v retrieving revision 1.254 diff -u -p -u -r1.254 vmm.c --- sys/arch/amd64/amd64/vmm.c 22 Sep 2019 08:47:54 -0000 1.254 +++ sys/arch/amd64/amd64/vmm.c 15 Feb 2020 23:26:47 -0000 @@ -202,6 +202,7 @@ void vmx_setmsrbrw(struct vcpu *, uint32 void svm_set_clean(struct vcpu *, uint32_t); void svm_set_dirty(struct vcpu *, uint32_t); +int vmm_gpa_is_valid(struct vcpu *vcpu, paddr_t gpa, size_t obj_size); void vmm_init_pvclock(struct vcpu *, paddr_t); int vmm_update_pvclock(struct vcpu *); @@ -6875,9 +6876,45 @@ vmm_free_vpid(uint16_t vpid) rw_exit_write(&vmm_softc->vpid_lock); } + +/* vmm_gpa_is_valid + * + * Check if the given gpa is within guest memory space. + * + * Parameters: + * vcpu: The virtual cpu we are running on. + * gpa: The address to check. + * obj_size: The size of the object assigned to gpa + * + * Return values: + * 1: gpa is within the memory ranges allocated for the vcpu + * 0: otherwise + */ +int +vmm_gpa_is_valid(struct vcpu *vcpu, paddr_t gpa, size_t obj_size) +{ + struct vm *vm = vcpu->vc_parent; + struct vm_mem_range *vmr; + for (size_t i = 0; i < vm->vm_nmemranges; ++i) { + vmr = &vm->vm_memranges[i]; + if (vmr->vmr_gpa <= gpa && + gpa < (vmr->vmr_gpa + vmr->vmr_size - obj_size)) { + return 1; + } + } + return 0; +} + void vmm_init_pvclock(struct vcpu *vcpu, paddr_t gpa) { + if (!vmm_gpa_is_valid(vcpu, gpa & 0xFFFFFFFFFFFFFFF0, + sizeof(struct pvclock_time_info))) { + /* XXX: Kill guest? */ + vmm_inject_gp(vcpu); + return; + } + vcpu->vc_pvclock_system_gpa = gpa; vcpu->vc_pvclock_system_tsc_mul = (int) ((1000000000L << 20) / tc_getfrequency());