mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
domctl: relax getdomaininfo permissions
Qemu needs access to this for the domain it controls, both due to it being used by xc_domain_memory_mapping() (which qemu calls) and the explicit use in hw/xenpv/xen_domainbuild.c:xen_domain_poll(). Extend permissions to that of any "ordinary" domctl: A domain controlling the targeted domain can invoke this operation for that target domain (which is being achieved by no longer passing NULL to xsm_domctl()). This at once avoids a for_each_domain() loop when the ID of an existing domain gets passed in. Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
This commit is contained in:
1 parent
c4e7a67e3a
commit
d9c91ccdcd
3 files changed
+24
-12
No files matched your search
@@ -149,7 +149,7 @@ define(`device_model', `
|
||||
create_channel($2, $1, $2_channel)
|
||||
allow $1 $2_channel:event create;
|
||||
|
||||
allow $1 $2_target:domain shutdown;
|
||||
allow $1 $2_target:domain { getdomaininfo shutdown };
|
||||
allow $1 $2_target:mmu { map_read map_write adjust physmap target_hack };
|
||||
allow $1 $2_target:hvm { getparam setparam trackdirtyvram hvmctl irqlevel pciroute pcilevel cacheattr send_irq };
|
||||
')
|
||||
|
||||
+18
-7
@@ -396,14 +396,13 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
|
||||
switch ( op->cmd )
|
||||
{
|
||||
case XEN_DOMCTL_createdomain:
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
case XEN_DOMCTL_test_assign_device:
|
||||
case XEN_DOMCTL_gdbsx_guestmemio:
|
||||
d = NULL;
|
||||
break;
|
||||
default:
|
||||
d = rcu_lock_domain_by_id(op->domain);
|
||||
if ( d == NULL )
|
||||
if ( !d && op->cmd != XEN_DOMCTL_getdomaininfo )
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
@@ -817,14 +816,22 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
|
||||
|
||||
case XEN_DOMCTL_getdomaininfo:
|
||||
{
|
||||
domid_t dom = op->domain;
|
||||
domid_t dom = DOMID_INVALID;
|
||||
|
||||
rcu_read_lock(&domlist_read_lock);
|
||||
|
||||
for_each_domain ( d )
|
||||
if ( d->domain_id >= dom )
|
||||
if ( !d )
|
||||
{
|
||||
ret = -EINVAL;
|
||||
if ( op->domain >= DOMID_FIRST_RESERVED )
|
||||
break;
|
||||
|
||||
rcu_read_lock(&domlist_read_lock);
|
||||
|
||||
dom = op->domain;
|
||||
for_each_domain ( d )
|
||||
if ( d->domain_id >= dom )
|
||||
break;
|
||||
}
|
||||
|
||||
ret = -ESRCH;
|
||||
if ( d == NULL )
|
||||
goto getdomaininfo_out;
|
||||
@@ -839,6 +846,10 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
|
||||
copyback = 1;
|
||||
|
||||
getdomaininfo_out:
|
||||
/* When d was non-NULL upon entry, no cleanup is needed. */
|
||||
if ( dom == DOMID_INVALID )
|
||||
break;
|
||||
|
||||
rcu_read_unlock(&domlist_read_lock);
|
||||
d = NULL;
|
||||
break;
|
||||
|
||||
@@ -61,7 +61,12 @@ static always_inline int xsm_default_action(
|
||||
return 0;
|
||||
case XSM_TARGET:
|
||||
if ( src == target )
|
||||
{
|
||||
return 0;
|
||||
case XSM_XS_PRIV:
|
||||
if ( src->is_xenstore )
|
||||
return 0;
|
||||
}
|
||||
/* fall through */
|
||||
case XSM_DM_PRIV:
|
||||
if ( target && src->target == target )
|
||||
@@ -71,10 +76,6 @@ static always_inline int xsm_default_action(
|
||||
if ( src->is_privileged )
|
||||
return 0;
|
||||
return -EPERM;
|
||||
case XSM_XS_PRIV:
|
||||
if ( src->is_xenstore || src->is_privileged )
|
||||
return 0;
|
||||
return -EPERM;
|
||||
default:
|
||||
LINKER_BUG_ON(1);
|
||||
return -EPERM;
|
||||
|
||||