git: 2dea4de8e0f0 - stable/14 - vmm: Properly handle writes spanning across two pages in vm_handle_db
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 06 Oct 2024 15:01:45 UTC
The branch stable/14 has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=2dea4de8e0f0ee886cf46a5ceddabd4192843445 commit 2dea4de8e0f0ee886cf46a5ceddabd4192843445 Author: Bojan Novković <bnovkov@FreeBSD.org> AuthorDate: 2024-09-29 11:10:10 +0000 Commit: Ed Maste <emaste@FreeBSD.org> CommitDate: 2024-10-06 15:01:24 +0000 vmm: Properly handle writes spanning across two pages in vm_handle_db The vm_handle_db function is responsible for writing correct status register values into memory when a guest VM is being single-stepped using the RFLAGS.TF mechanism. However, it currently does not properly handle an edge case where the resulting write spans across two pages. This commit fixes this by making vm_handle_db use two vm_copy_info structs. Security: HYP-09 Reviewed by: markj (cherry picked from commit 51fda658baa3f80c9778f3a9873fbf67df87119b) --- sys/amd64/vmm/vmm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index f399f876717d..ef4c7a9af2ea 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -1771,7 +1771,7 @@ vm_handle_db(struct vcpu *vcpu, struct vm_exit *vme, bool *retu) int error, fault; uint64_t rsp; uint64_t rflags; - struct vm_copyinfo copyinfo; + struct vm_copyinfo copyinfo[2]; *retu = true; if (!vme->u.dbg.pushf_intercept || vme->u.dbg.tf_shadow_val != 0) { @@ -1780,21 +1780,21 @@ vm_handle_db(struct vcpu *vcpu, struct vm_exit *vme, bool *retu) vm_get_register(vcpu, VM_REG_GUEST_RSP, &rsp); error = vm_copy_setup(vcpu, &vme->u.dbg.paging, rsp, sizeof(uint64_t), - VM_PROT_RW, ©info, 1, &fault); + VM_PROT_RW, copyinfo, nitems(copyinfo), &fault); if (error != 0 || fault != 0) { *retu = false; return (EINVAL); } /* Read pushed rflags value from top of stack. */ - vm_copyin(©info, &rflags, sizeof(uint64_t)); + vm_copyin(copyinfo, &rflags, sizeof(uint64_t)); /* Clear TF bit. */ rflags &= ~(PSL_T); /* Write updated value back to memory. */ - vm_copyout(&rflags, ©info, sizeof(uint64_t)); - vm_copy_teardown(©info, 1); + vm_copyout(&rflags, copyinfo, sizeof(uint64_t)); + vm_copy_teardown(copyinfo, nitems(copyinfo)); return (0); }