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

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



commit 9abd8482f15eb12bc3c1f7f57e26b625c93e0e05
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Jun 4 21:41:59 2026 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Thu Jun 4 22:29:01 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   |  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 5bcd4a32cd..c68ffb7337 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -480,6 +480,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 71d2898174..8f4bfc0936 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -602,11 +602,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 0af668910b..981cd3bf18 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -650,13 +650,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 fc30cf822f..f2bbe3ed8b 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -154,8 +154,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
@@ -634,12 +632,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 44a9e04ae7..95170547fc 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -110,8 +110,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 4aa91a3dd6..7d9ebe3d6b 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:
@@ -1349,11 +1347,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)
 {
@@ -1937,8 +1930,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.18



 


Rackspace

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