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: 705ea2b54c ("New VCPUOP_register_runstate_memory_area hypercall.")
Signed-off-by: Roger Pau Monné <roger@xenproject.org>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Roger Pau Monne committed 2026-10-27 11:02:17 +01:00
1 parent b07838dc46
commit 8b0a70ddd2
3 files changed
+15

No files matched your search

+5
View File
@@ -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);
+9
View File
@@ -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);
+1
View File
@@ -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
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.