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:
Jan Beulich committed 2016-08-17 15:31:56 +02:00
1 parent c4e7a67e3a
commit d9c91ccdcd
3 files changed
+24 -12

No files matched your search

+1 -1
View File
@@ -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
View File
@@ -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;
+5 -4
View File
@@ -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;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.