[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen master] xen/vcpu: ensure no write when runstate handler is NULL



commit 8b0a70ddd29dec2f86a49c21e3664a21e281e859
Author:     Roger Pau Monne <roger@xxxxxxxxxxxxxx>
AuthorDate: Fri Oct 23 15:25:09 2026 +0200
Commit:     Roger Pau Monne <roger@xxxxxxxxxxxxxx>
CommitDate: Tue Oct 27 11:02:17 2026 +0100

    xen/vcpu: ensure no write when runstate handler is NULL
    
    The VCPUOP_register_runstate_memory_area hypercall tries to update the
    newly registered area, even when NULL is being registered.  If the guest
    happens to have memory mapped at 0 in the address space, this write will
    succeed.
    
    Ever since it's introduction in Xen 3.0, NULL is the initial state of the
    pointer, and guards the update of the runstate area in context_switch().
    NULL has also been accepted as an input to the hypercall.
    
    It is unclear whether de-registration of the area was considered at the
    time, but the behaviour of the hypercall has always supported this.
    De-registering using NULL is a common pattern for other hypercalls, so
    formally make this the case for VCPUOP_register_runstate_memory_area by
    skipping the update if the area has been de-registered.
    
    Fixes: 705ea2b54c35 ("New VCPUOP_register_runstate_memory_area hypercall.")
    Signed-off-by: Roger Pau Monné <roger@xxxxxxxxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/arch/x86/x86_64/domain.c | 5 +++++
 xen/common/domain.c          | 9 +++++++++
 xen/include/public/vcpu.h    | 1 +
 3 files changed, 15 insertions(+)

diff --git a/xen/arch/x86/x86_64/domain.c b/xen/arch/x86/x86_64/domain.c
index a02d4f569e..533b0b21a0 100644
--- a/xen/arch/x86/x86_64/domain.c
+++ b/xen/arch/x86/x86_64/domain.c
@@ -58,6 +58,11 @@ compat_vcpu_op(int cmd, unsigned int vcpuid, 
XEN_GUEST_HANDLE_PARAM(void) arg)
         rc = 0;
         guest_from_compat_handle(v->runstate_guest.compat, area.addr.h);
 
+        /* NULL handle is deregistering the address. */
+        if ( compat_handle_is_null(area.addr.h) )
+            break;
+
+        /* Update the newly-registered runstate area, best-effort. */
         if ( v == current )
         {
             XLAT_vcpu_runstate_info(&info, &v->runstate);
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 6b52713518..b41be89cd0 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -2324,12 +2324,21 @@ long common_vcpu_op(int cmd, struct vcpu *v, 
XEN_GUEST_HANDLE_PARAM(void) arg)
         if ( copy_from_guest(&area, arg, 1) )
             break;
 
+        /* NULL handle is deregistering the address. */
+        if ( guest_handle_is_null(area.addr.h) )
+        {
+            runstate_guest(v) = area.addr.h;
+            rc = 0;
+            break;
+        }
+
         if ( !guest_handle_okay(area.addr.h, 1) )
             break;
 
         rc = 0;
         runstate_guest(v) = area.addr.h;
 
+        /* Update the newly-registered runstate area, best-effort. */
         if ( v == current )
         {
             __copy_to_guest(runstate_guest(v), &v->runstate, 1);
diff --git a/xen/include/public/vcpu.h b/xen/include/public/vcpu.h
index 5aea6ca709..9a8003e3ec 100644
--- a/xen/include/public/vcpu.h
+++ b/xen/include/public/vcpu.h
@@ -112,6 +112,7 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_t);
  *     VCPU was last scheduled to run.
  *  3. New code wants to prefer VCPUOP_register_runstate_phys_area, and only
  *     fall back to the operation here for backwards compatibility.
+ *  4. Passing a NULL handle will deregister the region.
  * @extra_arg == pointer to vcpu_register_runstate_memory_area structure.
  */
 #define VCPUOP_register_runstate_memory_area 5
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.