diff options
-rw-r--r-- | tools/flask/policy/policy/modules/xen/xen.if | 2 | ||||
-rw-r--r-- | xen/common/memory.c | 12 | ||||
-rw-r--r-- | xen/include/xsm/dummy.h | 7 | ||||
-rw-r--r-- | xen/include/xsm/xsm.h | 6 | ||||
-rw-r--r-- | xen/xsm/dummy.c | 1 | ||||
-rw-r--r-- | xen/xsm/flask/hooks.c | 6 | ||||
-rw-r--r-- | xen/xsm/flask/policy/access_vectors | 1 |
7 files changed, 34 insertions, 1 deletions
diff --git a/tools/flask/policy/policy/modules/xen/xen.if b/tools/flask/policy/policy/modules/xen/xen.if index fda5cb5b26..d9d534427b 100644 --- a/tools/flask/policy/policy/modules/xen/xen.if +++ b/tools/flask/policy/policy/modules/xen/xen.if @@ -30,6 +30,7 @@ define(`declare_domain', ` # containing at most one domain. This is not enforced by policy. define(`declare_singleton_domain', ` type $1, domain_type`'ifelse(`$#', `1', `', `,shift($@)'); + define(`$1_self', `$1') type $1_channel, event_type; type_transition $1 domain_type:event $1_channel; declare_domain_common($1, $1) @@ -161,6 +162,7 @@ define(`make_device_model', ` # use_device(domain, device) # Allow a device to be used by a domain define(`use_device', ` + allow $1 $1_self:mmu exchange; allow $1 $2:resource use; allow $1 domio_t:mmu { map_read map_write }; ') diff --git a/xen/common/memory.c b/xen/common/memory.c index 35acf1cb88..e18e224156 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -341,9 +341,19 @@ static long memory_exchange(XEN_GUEST_HANDLE_PARAM(xen_memory_exchange_t) arg) out_chunk_order = exch.in.extent_order - exch.out.extent_order; } - rc = rcu_lock_target_domain_by_id(exch.in.domid, &d); + d = rcu_lock_domain_by_any_id(exch.in.domid); + if ( d == NULL ) + { + rc = -ESRCH; + goto fail_early; + } + + rc = xsm_memory_exchange(d); if ( rc ) + { + rcu_unlock_domain(d); goto fail_early; + } memflags |= MEMF_bits(domain_clamp_alloc_bitsize( d, diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 6648739c38..9894d8d6d5 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -235,6 +235,13 @@ static XSM_INLINE int xsm_grant_query_size(struct domain *d1, struct domain *d2) return 0; } +static XSM_INLINE int xsm_memory_exchange(struct domain *d) +{ + if ( d != current->domain && !IS_PRIV_FOR(current->domain, d) ) + return -EPERM; + return 0; +} + static XSM_INLINE int xsm_memory_adjust_reservation(struct domain *d1, struct domain *d2) { diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index d41eb549bc..a8c1d875cc 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -96,6 +96,7 @@ struct xsm_operations { int (*get_pod_target) (struct domain *d); int (*set_pod_target) (struct domain *d); + int (*memory_exchange) (struct domain *d); int (*memory_adjust_reservation) (struct domain *d1, struct domain *d2); int (*memory_stat_reservation) (struct domain *d1, struct domain *d2); int (*memory_pin_page) (struct domain *d1, struct domain *d2, struct page_info *page); @@ -453,6 +454,11 @@ static inline int xsm_set_pod_target (struct domain *d) return xsm_ops->set_pod_target(d); } +static inline int xsm_memory_exchange (struct domain *d) +{ + return xsm_ops->memory_exchange(d); +} + static inline int xsm_memory_adjust_reservation (struct domain *d1, struct domain *d2) { diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 200cbc81bb..71299d56a2 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -84,6 +84,7 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, get_pod_target); set_to_dummy_if_null(ops, set_pod_target); + set_to_dummy_if_null(ops, memory_exchange); set_to_dummy_if_null(ops, memory_adjust_reservation); set_to_dummy_if_null(ops, memory_stat_reservation); set_to_dummy_if_null(ops, memory_pin_page); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index ad60a882bf..7707ac2654 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -396,6 +396,11 @@ static int flask_set_pod_target(struct domain *d) return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETPODTARGET); } +static int flask_memory_exchange(struct domain *d) +{ + return current_has_perm(d, SECCLASS_MMU, MMU__EXCHANGE); +} + static int flask_memory_adjust_reservation(struct domain *d1, struct domain *d2) { return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__ADJUST); @@ -1686,6 +1691,7 @@ static struct xsm_operations flask_ops = { .get_pod_target = flask_get_pod_target, .set_pod_target = flask_set_pod_target, + .memory_exchange = flask_memory_exchange, .memory_adjust_reservation = flask_memory_adjust_reservation, .memory_stat_reservation = flask_memory_stat_reservation, .memory_pin_page = flask_memory_pin_page, diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index 8324725e11..caf65d2d89 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -142,6 +142,7 @@ class mmu memorymap remote_remap mmuext_op + exchange } class shadow |