[PATCH v2] common: don't require use of DOMID_SELF

Jan Beulich posted 1 patch 3 years, 2 months ago
Test gitlab-ci passed
Patches applied successfully (tree, apply log)
git fetch https://gitlab.com/xen-project/patchew/xen tags/patchew/5ee17d3d-46a3-bba0-863b-6bd5947cf2e6@suse.com
[PATCH v2] common: don't require use of DOMID_SELF
Posted by Jan Beulich 3 years, 2 months ago
It's not overly difficult for a domain to figure out its ID, so
requiring the use of DOMID_SELF in a very limited set of places isn't
really helpful towards keeping the ID opaque to the guest.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
v2: Comment on this version specific behavior in the respective public
    headers.

--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -2776,15 +2776,19 @@ struct gnttab_copy_buf {
 static int gnttab_copy_lock_domain(domid_t domid, bool is_gref,
                                    struct gnttab_copy_buf *buf)
 {
-    /* Only DOMID_SELF may reference via frame. */
-    if ( domid != DOMID_SELF && !is_gref )
-        return GNTST_permission_denied;
-
     buf->domain = rcu_lock_domain_by_any_id(domid);
 
     if ( !buf->domain )
         return GNTST_bad_domain;
 
+    /* Only the local domain may reference via frame. */
+    if ( buf->domain != current->domain && !is_gref )
+    {
+        rcu_unlock_domain(buf->domain);
+        buf->domain = NULL;
+        return GNTST_permission_denied;
+    }
+
     buf->ptr.domid = domid;
 
     return GNTST_okay;
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -2566,13 +2566,7 @@ __initcall(register_heap_trigger);
 
 struct domain *get_pg_owner(domid_t domid)
 {
-    struct domain *pg_owner = NULL, *curr = current->domain;
-
-    if ( unlikely(domid == curr->domain_id) )
-    {
-        gdprintk(XENLOG_WARNING, "Cannot specify itself as foreign domain\n");
-        goto out;
-    }
+    struct domain *pg_owner;
 
     switch ( domid )
     {
@@ -2590,7 +2584,6 @@ struct domain *get_pg_owner(domid_t domi
         break;
     }
 
- out:
     return pg_owner;
 }
 
--- a/xen/include/public/grant_table.h
+++ b/xen/include/public/grant_table.h
@@ -447,6 +447,12 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_
  * source_offset specifies an offset in the source frame, dest_offset
  * the offset in the target frame and  len specifies the number of
  * bytes to be copied.
+ *
+ * Note that operations not specifying GNTCOPY_*_gref will be restricted
+ * to the local domain for the respective operands (source and/or
+ * destination.  Note further that prior to Xen 4.15 only DOMID_SELF
+ * would be accepted to specify this, i.e. the actual ID of the local
+ * domain can only be used successfully on 4.15 and newer.
  */
 
 #define _GNTCOPY_source_gref      (0)
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -215,7 +215,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
  * @count is the length of the above array.
  * @pdone is an output parameter indicating number of completed operations
  * @foreigndom[15:0]: FD, the expected owner of data pages referenced in this
- *                    hypercall invocation. Can be DOMID_SELF.
+ *                    hypercall invocation. Can be DOMID_SELF or, for
+ *                    privileged callers, DOMID_IO or DOMID_XEN (see below).
+ *                    The calling domain can also be identified by its actual
+ *                    ID, but this will only work on Xen 4.15 and newer.
  * @foreigndom[31:16]: PFD, the expected owner of pagetable pages referenced
  *                     in this hypercall invocation. The value of this field
  *                     (x) encodes the PFD as follows:
@@ -364,7 +367,9 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
  * `                      unsigned int foreigndom)
  */
 /* HYPERVISOR_mmuext_op() accepts a list of mmuext_op structures.
- * A foreigndom (FD) can be specified (or DOMID_SELF for none).
+ * A foreigndom (FD) can be specified (or DOMID_SELF for none; the calling
+ * domain can also be identified by its actual ID, but this will only work
+ * on Xen 4.15 and newer).
  * Where the FD has some effect, it is described below.
  *
  * cmd: MMUEXT_(UN)PIN_*_TABLE
@@ -481,6 +486,11 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
  * ` @va: The virtual address whose mapping we want to change
  * ` @val: The new page table entry, must contain a machine address
  * ` @flags: Control TLB flushes
+ * ` @domid: The expected owner of data page referenced in this hypercall
+ * `         invocation. Can be DOMID_SELF or, for privileged callers, DOMID_IO
+ * `         or DOMID_XEN (see below). The calling domain can also be
+ * `         identified by its actual ID, but this will only work on Xen 4.15
+ * `         and newer.
  */
 /* These are passed as 'flags' to update_va_mapping. They can be ORed. */
 /* When specifying UVMF_MULTI, also OR in a pointer to a CPU bitmap.   */