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

[xen staging-4.17] domctl/XSM: drop vm_event_control hook



commit a0119e1fd676b350491a0e6441eae63fa144d2f9
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Jun 4 21:42:55 2026 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Thu Jun 4 22:29:12 2026 +0100

    domctl/XSM: drop vm_event_control hook
    
    Integrate the checking with xsm_domctl(). Care needs to be taken with the
    GET_VERSION sub-op, which may be invoked with DOMID_INVALID, and which has
    been (and continues to be) bypassing XSM checking.
    
    Since the latter two parameters were unused, monitor_domctl() invoking the
    hook was actually redundant with the earlier xsm_domctl() (as can be seen
    nicely from the hunks changing xsm/flask/hooks.c).
    
    As a positive side effect, permissions are then checked at the same early
    point with and without Flask.
    
    While folding XEN_DOMCTL_monitor_op and XEN_DOMCTL_vm_event_op in
    flask_domctl(), also fold in XEN_DOMCTL_set_access_required.
    
    This is part of XSA-492.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Daniel P. Smith <dpsmith@xxxxxxxxxxxxxxxxxxxx>
    Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    (cherry picked from commit b4a7c17146f4363750d26cb2dcee08b480625a3d)
---
 xen/common/domctl.c     | 17 +++++++++++++++++
 xen/common/monitor.c    |  5 -----
 xen/common/vm_event.c   |  4 ----
 xen/include/xsm/dummy.h |  7 -------
 xen/include/xsm/xsm.h   |  8 --------
 xen/xsm/dummy.c         |  2 --
 xen/xsm/flask/hooks.c   | 11 +----------
 7 files changed, 18 insertions(+), 36 deletions(-)

diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index ebc97aa843..03851eb221 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -510,6 +510,23 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) 
u_domctl)
         goto domctl_out_unlock_domonly;
     }
 
+    case XEN_DOMCTL_vm_event_op:
+        if ( op->u.vm_event_op.op == XEN_VM_EVENT_GET_VERSION )
+        {
+            /* No XSM check (and potentially d == NULL) here. */
+            ret = vm_event_domctl(d, &op->u.vm_event_op);
+            if ( !ret )
+                copyback = true;
+            goto domctl_out_unlock_domonly;
+        }
+        if ( !d )
+        {
+            ret = -ESRCH;
+            goto domctl_out_unlock_domonly;
+        }
+        /* Other sub-ops handled further down. */
+        break;
+
     case XEN_DOMCTL_ioport_permission:
     case XEN_DOMCTL_ioport_mapping:
     case XEN_DOMCTL_bind_pt_irq:
diff --git a/xen/common/monitor.c b/xen/common/monitor.c
index d5c9ff1cbf..aec6391faf 100644
--- a/xen/common/monitor.c
+++ b/xen/common/monitor.c
@@ -30,16 +30,11 @@
 
 int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop)
 {
-    int rc;
     bool requested_status = false;
 
     if ( unlikely(current->domain == d) ) /* no domain_pause() */
         return -EPERM;
 
-    rc = xsm_vm_event_control(XSM_PRIV, d, mop->op, mop->event);
-    if ( unlikely(rc) )
-        return rc;
-
     switch ( mop->op )
     {
     case XEN_DOMCTL_MONITOR_OP_ENABLE:
diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index ecf49c38a9..6af5f13f45 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -600,10 +600,6 @@ int vm_event_domctl(struct domain *d, struct 
xen_domctl_vm_event_op *vec)
         return 0;
     }
 
-    rc = xsm_vm_event_control(XSM_PRIV, d, vec->mode, vec->op);
-    if ( rc )
-        return rc;
-
     if ( unlikely(d == current->domain) ) /* no domain_pause() */
     {
         gdprintk(XENLOG_INFO, "Tried to do a memory event op on itself.\n");
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index 9e45b0e535..0613345669 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -643,13 +643,6 @@ static XSM_INLINE int cf_check xsm_hvm_altp2mhvm_op(
     }
 }
 
-static XSM_INLINE int cf_check xsm_vm_event_control(
-    XSM_DEFAULT_ARG struct domain *d, int mode, int op)
-{
-    XSM_ASSERT_ACTION(XSM_PRIV);
-    return xsm_default_action(action, current->domain, d);
-}
-
 #ifdef CONFIG_MEM_ACCESS
 static XSM_INLINE int cf_check xsm_mem_access(XSM_DEFAULT_ARG struct domain *d)
 {
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 627c0d2731..2a3b94afd5 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -152,8 +152,6 @@ struct xsm_ops {
     int (*hvm_altp2mhvm_op)(struct domain *d, uint64_t mode, uint32_t op);
     int (*get_vnumainfo)(struct domain *d);
 
-    int (*vm_event_control)(struct domain *d, int mode, int op);
-
 #ifdef CONFIG_MEM_ACCESS
     int (*mem_access)(struct domain *d);
 #endif
@@ -626,12 +624,6 @@ static inline int xsm_get_vnumainfo(xsm_default_t def, 
struct domain *d)
     return alternative_call(xsm_ops.get_vnumainfo, d);
 }
 
-static inline int xsm_vm_event_control(
-    xsm_default_t def, struct domain *d, int mode, int op)
-{
-    return alternative_call(xsm_ops.vm_event_control, d, mode, op);
-}
-
 #ifdef CONFIG_MEM_ACCESS
 static inline int xsm_mem_access(xsm_default_t def, struct domain *d)
 {
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index e6ffa948f7..fba0672fdd 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -109,8 +109,6 @@ static const struct xsm_ops __initconst_cf_clobber 
dummy_ops = {
     .remove_from_physmap           = xsm_remove_from_physmap,
     .map_gmfn_foreign              = xsm_map_gmfn_foreign,
 
-    .vm_event_control              = xsm_vm_event_control,
-
 #ifdef CONFIG_MEM_ACCESS
     .mem_access                    = xsm_mem_access,
 #endif
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index b0308369c9..8ebbf08a42 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -693,7 +693,6 @@ static int cf_check flask_domctl(struct domain *d, unsigned 
int cmd,
     /* These have individual XSM hooks (common/domctl.c) */
     case XEN_DOMCTL_scheduler_op:
     case XEN_DOMCTL_set_target:
-    case XEN_DOMCTL_vm_event_op:
 
 #ifdef CONFIG_X86
     /* These have individual XSM hooks (arch/x86/domctl.c) */
@@ -787,9 +786,8 @@ static int cf_check flask_domctl(struct domain *d, unsigned 
int cmd,
         return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__TRIGGER);
 
     case XEN_DOMCTL_set_access_required:
-        return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__VM_EVENT);
-
     case XEN_DOMCTL_monitor_op:
+    case XEN_DOMCTL_vm_event_op:
         return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__VM_EVENT);
 
     case XEN_DOMCTL_debug_op:
@@ -1346,11 +1344,6 @@ static int cf_check flask_hvm_altp2mhvm_op(struct domain 
*d, uint64_t mode, uint
     return current_has_perm(d, SECCLASS_HVM, HVM__ALTP2MHVM_OP);
 }
 
-static int cf_check flask_vm_event_control(struct domain *d, int mode, int op)
-{
-    return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__VM_EVENT);
-}
-
 #ifdef CONFIG_MEM_ACCESS
 static int cf_check flask_mem_access(struct domain *d)
 {
@@ -1929,8 +1922,6 @@ static const struct xsm_ops __initconst_cf_clobber 
flask_ops = {
     .do_xsm_op = do_flask_op,
     .get_vnumainfo = flask_get_vnumainfo,
 
-    .vm_event_control = flask_vm_event_control,
-
 #ifdef CONFIG_MEM_ACCESS
     .mem_access = flask_mem_access,
 #endif
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.17



 


Rackspace

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