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

[xen master] domctl/XSM: drop vm_event_control hook



commit b4a7c17146f4363750d26cb2dcee08b480625a3d
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Jun 4 20:20:44 2026 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Tue Jun 9 12:45:56 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>
---
 xen/common/domctl.c     | 17 +++++++++++++++++
 xen/common/monitor.c    |  5 -----
 xen/common/vm_event.c   |  9 ++++-----
 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, 22 insertions(+), 37 deletions(-)

diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 4bb4be009b..d22fa089e1 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -496,6 +496,23 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) 
u_domctl)
     }
 #endif
 
+    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_gsi_permission:
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 cf0258223f..6f62755af8 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -604,11 +604,10 @@ int vm_event_domctl(struct domain *d, struct 
xen_domctl_vm_event_op *vec)
 
     /* All other subops need to target a real domain. */
     if ( unlikely(d == NULL) )
-        return -ESRCH;
-
-    rc = xsm_vm_event_control(XSM_PRIV, d, vec->mode, vec->op);
-    if ( rc )
-        return rc;
+    {
+        ASSERT_UNREACHABLE();
+        return -EILSEQ;
+    }
 
     if ( unlikely(d == current->domain) ) /* no domain_pause() */
     {
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index d4e3e27ab4..ed2bcc6521 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -646,13 +646,6 @@ static XSM_INLINE int cf_check xsm_hvm_altp2mhvm_op(
 }
 
 #ifdef CONFIG_VM_EVENT
-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);
-}
-
 static XSM_INLINE int cf_check xsm_mem_access(XSM_DEFAULT_ARG struct domain *d)
 {
     XSM_ASSERT_ACTION(XSM_DM_PRIV);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 2708d5ecba..cce0972f53 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -156,8 +156,6 @@ struct xsm_ops {
     int (*get_vnumainfo)(struct domain *d);
 
 #ifdef CONFIG_VM_EVENT
-    int (*vm_event_control)(struct domain *d, int mode, int op);
-
     int (*mem_access)(struct domain *d);
 #endif
 
@@ -651,12 +649,6 @@ static inline int xsm_get_vnumainfo(xsm_default_t def, 
struct domain *d)
 }
 
 #ifdef CONFIG_VM_EVENT
-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);
-}
-
 static inline int xsm_mem_access(xsm_default_t def, struct domain *d)
 {
     return alternative_call(xsm_ops.mem_access, d);
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index 9b0eab4bfc..31ee287d68 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -115,8 +115,6 @@ static const struct xsm_ops __initconst_cf_clobber 
dummy_ops = {
     .map_gmfn_foreign              = xsm_map_gmfn_foreign,
 
 #ifdef CONFIG_VM_EVENT
-    .vm_event_control              = xsm_vm_event_control,
-
     .mem_access                    = xsm_mem_access,
 #endif
 
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 14df9b78d4..51188f33f3 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -666,7 +666,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) */
@@ -760,9 +759,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:
@@ -1332,11 +1330,6 @@ static int cf_check flask_hvm_altp2mhvm_op(struct domain 
*d, uint64_t mode, uint
 }
 
 #ifdef CONFIG_VM_EVENT
-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);
-}
-
 static int cf_check flask_mem_access(struct domain *d)
 {
     return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__MEM_ACCESS);
@@ -1933,8 +1926,6 @@ static const struct xsm_ops __initconst_cf_clobber 
flask_ops = {
     .get_vnumainfo = flask_get_vnumainfo,
 
 #ifdef CONFIG_VM_EVENT
-    .vm_event_control = flask_vm_event_control,
-
     .mem_access = flask_mem_access,
 #endif
 
--
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®.