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());