mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
To shield the sysctl lock from abuse by unauthorized domains, follow what
5154fdda11 ("domctl: protect locking for get_domain_state") did: Check
for permission to issue the operation against DOM_XEN in flask_sysctl().
The finer-grained xsm_getdomaininfo() later in the handling of the sub-op
remains unaltered.
In the in-tree policy respective permission therefore needs granting.
This is part of CVE-2026-62426 / XSA-499.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
385 lines
8.0 KiB
Plaintext
385 lines
8.0 KiB
Plaintext
# Macro definitions for FLASK policy
|
|
|
|
################################################################################
|
|
#
|
|
# Domain creation and setup
|
|
#
|
|
################################################################################
|
|
define(`declare_domain_common', `
|
|
allow $1 $2:grant {
|
|
query
|
|
setup
|
|
};
|
|
allow $1 $2:mmu {
|
|
adjust
|
|
physmap
|
|
map_read
|
|
map_write
|
|
stat
|
|
pinpage
|
|
updatemp
|
|
mmuext_op
|
|
};
|
|
allow $1 $2:hvm {
|
|
getparam
|
|
setparam
|
|
altp2mhvm_op
|
|
};
|
|
allow $1 $2:domain2 get_vnumainfo;
|
|
')
|
|
|
|
# declare_domain(type, attrs...)
|
|
# Declare a domain type, along with associated _self and _channel types
|
|
# Allow the domain to perform basic operations on itself
|
|
define(`declare_domain', `
|
|
type $1, domain_type`'ifelse(`$#', `1', `', `,shift($@)');
|
|
type $1_self, domain_type, domain_self_type;
|
|
type_transition $1 $1:domain $1_self;
|
|
type $1_channel, event_type;
|
|
type_transition $1 domain_type:event $1_channel;
|
|
declare_domain_common($1, $1_self)
|
|
')
|
|
|
|
# declare_singleton_domain(type, attrs...)
|
|
# Declare a domain type and associated _channel types.
|
|
# Note: Because the domain can perform basic operations on itself and any
|
|
# other domain of the same type, this constructor should be used for types
|
|
# 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)
|
|
')
|
|
|
|
# declare_build_label(type)
|
|
# Declare a paired _building type for the given domain type
|
|
define(`declare_build_label', `
|
|
type $1_building, domain_type;
|
|
type_transition $1_building domain_type:event $1_channel;
|
|
allow $1_building $1 : domain transition;
|
|
')
|
|
|
|
define(`create_domain_common', `
|
|
allow $1 $2:domain {
|
|
create
|
|
max_vcpus
|
|
setdomainmaxmem
|
|
setaddrsize
|
|
getdomaininfo
|
|
hypercall
|
|
setvcpucontext
|
|
getscheduler
|
|
getvcpuinfo
|
|
getaddrsize
|
|
getaffinity
|
|
setaffinity
|
|
settime
|
|
setdomainhandle
|
|
getvcpucontext
|
|
set_misc_info
|
|
getpagingmempool
|
|
setpagingmempool
|
|
};
|
|
allow $1 $2:domain2 {
|
|
set_cpu_policy
|
|
settsc
|
|
setscheduler
|
|
setclaim
|
|
set_vnumainfo
|
|
get_vnumainfo
|
|
cacheflush
|
|
psr_cmt_op
|
|
psr_alloc
|
|
soft_reset
|
|
resource_map
|
|
get_cpu_policy
|
|
vuart_op
|
|
set_llc_colors
|
|
get_domain_state
|
|
};
|
|
allow $1 $2:security check_context;
|
|
allow $1 $2:shadow enable;
|
|
allow $1 $2:mmu {
|
|
map_read
|
|
map_write
|
|
adjust
|
|
memorymap
|
|
physmap
|
|
pinpage
|
|
mmuext_op
|
|
updatemp
|
|
};
|
|
allow $1 $2:grant setup;
|
|
allow $1 $2:hvm {
|
|
getparam
|
|
hvmctl
|
|
sethvmc
|
|
setparam
|
|
altp2mhvm
|
|
altp2mhvm_op
|
|
dm
|
|
};
|
|
')
|
|
|
|
# xen_build_domain(target)
|
|
# Allow a domain to be created at boot by the hypervisor
|
|
define(`xen_build_domain', `
|
|
allow xenboot_t $1:domain create;
|
|
allow xenboot_t $1_channel:event create;
|
|
')
|
|
|
|
# create_domain(priv, target)
|
|
# Allow a domain to be created directly
|
|
define(`create_domain', `
|
|
create_domain_common($1, $2)
|
|
allow $1 $2_channel:event create;
|
|
')
|
|
|
|
# create_domain_build_label(priv, target)
|
|
# Allow a domain to be created via its domain build label
|
|
define(`create_domain_build_label', `
|
|
create_domain_common($1, $2_building)
|
|
allow $1 $2_channel:event create;
|
|
allow $1 $2_building:domain2 relabelfrom;
|
|
allow $1 $2:domain2 relabelto;
|
|
allow $2_building $2:domain transition;
|
|
')
|
|
|
|
# manage_domain(priv, target)
|
|
# Allow managing a running domain
|
|
define(`manage_domain', `
|
|
allow $1 domxen_t:domain getdomaininfo;
|
|
allow $1 $2:domain {
|
|
getdomaininfo
|
|
getvcpuinfo
|
|
getaffinity
|
|
getaddrsize
|
|
pause
|
|
unpause
|
|
trigger
|
|
shutdown
|
|
destroy
|
|
setaffinity
|
|
setdomainmaxmem
|
|
getscheduler
|
|
resume
|
|
setpodtarget
|
|
getpodtarget
|
|
getpagingmempool
|
|
setpagingmempool
|
|
};
|
|
allow $1 $2:domain2 {
|
|
set_vnumainfo
|
|
dt_overlay
|
|
get_domain_state
|
|
};
|
|
')
|
|
|
|
# migrate_domain_out(priv, target)
|
|
# Allow creation of a snapshot or migration image from a domain
|
|
# (inbound migration is the same as domain creation)
|
|
define(`migrate_domain_out', `
|
|
allow $1 domxen_t:mmu map_read;
|
|
allow $1 $2:hvm {
|
|
gethvmc
|
|
getparam
|
|
};
|
|
allow $1 $2:mmu {
|
|
stat
|
|
pageinfo
|
|
map_read
|
|
};
|
|
allow $1 $2:domain {
|
|
getaddrsize
|
|
getvcpucontext
|
|
pause
|
|
destroy
|
|
};
|
|
allow $1 $2:domain2 gettsc;
|
|
allow $1 $2:shadow {
|
|
enable
|
|
disable
|
|
logdirty
|
|
};
|
|
')
|
|
|
|
################################################################################
|
|
#
|
|
# Inter-domain communication
|
|
#
|
|
################################################################################
|
|
|
|
# create_channel(source, dest, chan-label)
|
|
# This allows an event channel to be created from domains with labels
|
|
# <source> to <dest> and will label it <chan-label>
|
|
define(`create_channel', `
|
|
allow $1 $3:event {
|
|
create
|
|
send
|
|
status
|
|
};
|
|
allow $3 $2:event {
|
|
bind
|
|
};
|
|
')
|
|
|
|
# domain_event_comms(dom1, dom2)
|
|
# Allow two domain types to communicate using event channels
|
|
define(`domain_event_comms', `
|
|
create_channel($1, $2, $1_channel)
|
|
create_channel($2, $1, $2_channel)
|
|
')
|
|
|
|
# domain_comms(dom1, dom2)
|
|
# Allow two domain types to communicate using grants and event channels
|
|
define(`domain_comms', `
|
|
domain_event_comms($1, $2)
|
|
allow $1 $2:grant {
|
|
map_read
|
|
map_write
|
|
copy
|
|
unmap
|
|
};
|
|
allow $2 $1:grant {
|
|
map_read
|
|
map_write
|
|
copy
|
|
unmap
|
|
};
|
|
')
|
|
|
|
# domain_self_comms(domain)
|
|
# Allow a non-singleton domain type to communicate with itself using grants
|
|
# and event channels
|
|
define(`domain_self_comms', `
|
|
create_channel($1, $1_self, $1_channel)
|
|
allow $1 $1_self:grant {
|
|
map_read
|
|
map_write
|
|
copy
|
|
unmap
|
|
};
|
|
')
|
|
|
|
# device_model(dm_dom, hvm_dom)
|
|
# Define how a device model domain interacts with its target
|
|
define(`device_model', `
|
|
type $2_target, domain_type, domain_target_type;
|
|
type_transition $2 $1:domain $2_target;
|
|
allow $1 $2:domain set_target;
|
|
|
|
type_transition $2_target domain_type:event $2_channel;
|
|
create_channel($1, $2_target, $1_channel)
|
|
create_channel($2, $1, $2_channel)
|
|
allow $1 $2_channel:event create;
|
|
|
|
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
|
|
hvmctl
|
|
dm
|
|
};
|
|
allow $1 $2_target:domain2 resource_map;
|
|
')
|
|
|
|
# make_device_model(priv, dm_dom, hvm_dom)
|
|
# Allow creation of a device model and HVM domain pair
|
|
define(`make_device_model', `
|
|
device_model($2, $3)
|
|
allow $1 $2:domain2 make_priv_for;
|
|
allow $1 $3:domain2 set_as_target;
|
|
')
|
|
################################################################################
|
|
#
|
|
# Device types and delegation (PCI passthrough)
|
|
#
|
|
################################################################################
|
|
|
|
# use_device_iommu(domain, device)
|
|
# Allow a device to be used by a domain
|
|
# only if an IOMMU provides isolation.
|
|
define(`use_device_iommu', `
|
|
allow $1 $1_self:mmu exchange;
|
|
allow $1 $2:resource use_iommu;
|
|
allow $1 domio_t:mmu {
|
|
map_read
|
|
map_write
|
|
};
|
|
')
|
|
|
|
# use_device_iommu_nointremap(domain, device)
|
|
# Allow a device to be used by a domain
|
|
# only if an IOMMU is active, even if it does not support
|
|
# interrupt remapping.
|
|
# Allows acceptance of (typically older) less isolating hardware.
|
|
define(`use_device_iommu_nointremap', `
|
|
allow $1 $1_self:mmu exchange;
|
|
allow $1 $2:resource {
|
|
use_iommu
|
|
use_iommu_nointremap
|
|
};
|
|
allow $1 domio_t:mmu {
|
|
map_read
|
|
map_write
|
|
};
|
|
')
|
|
|
|
# use_device_noiommu(domain, device)
|
|
# Allow a device to be used by a domain
|
|
# even without an IOMMU available.
|
|
define(`use_device_noiommu', `
|
|
allow $1 $1_self:mmu exchange;
|
|
allow $1 $2:resource {
|
|
use_iommu
|
|
use_iommu_nointremap
|
|
use_noiommu
|
|
};
|
|
allow $1 domio_t:mmu {
|
|
map_read
|
|
map_write
|
|
};
|
|
')
|
|
|
|
# admin_device(domain, device)
|
|
# Allow a device to be used and delegated by a domain
|
|
define(`admin_device', `
|
|
allow $1 $2:resource {
|
|
setup
|
|
stat_device
|
|
add_device
|
|
add_irq
|
|
add_iomem
|
|
add_ioport
|
|
remove_device
|
|
remove_irq
|
|
remove_iomem
|
|
remove_ioport
|
|
plug
|
|
unplug
|
|
};
|
|
allow $1 $2:hvm bind_irq;
|
|
use_device_noiommu($1, $2)
|
|
')
|
|
|
|
# delegate_devices(priv-domain, target-domain)
|
|
# Allow devices to be delegated
|
|
define(`delegate_devices', `
|
|
allow $1 $2:resource {
|
|
add
|
|
remove
|
|
};
|
|
')
|