1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
# 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 };
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 $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;
')
# 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 };
')
|