Mailing List Archive

[PATCH 02/19] flask/policy: Add domain relabel example
This adds the nomigrate_t type to the example FLASK policy which allows
domains to be created that dom0 cannot access after building.

Example domain configuration snippet:
seclabel='customer_1:vm_r:nomigrate_t'
init_seclabel='customer_1:vm_r:nomigrate_t_building'

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
docs/misc/xsm-flask.txt | 2 +
tools/flask/policy/policy/modules/xen/xen.if | 56 +++++++++++++++++++++-------
tools/flask/policy/policy/modules/xen/xen.te | 10 +++++
3 files changed, 55 insertions(+), 13 deletions(-)

diff --git a/docs/misc/xsm-flask.txt b/docs/misc/xsm-flask.txt
index 6b0d327..0778a28 100644
--- a/docs/misc/xsm-flask.txt
+++ b/docs/misc/xsm-flask.txt
@@ -60,6 +60,8 @@ that can be used without dom0 disaggregation. The main types for domUs are:
- domU_t is a domain that can communicate with any other domU_t
- isolated_domU_t can only communicate with dom0
- prot_domU_t is a domain type whose creation can be disabled with a boolean
+ - nomigrate_t is a domain that must be created via the nomigrate_t_building
+ type, and whose memory cannot be read by dom0 once created

HVM domains with stubdomain device models use two types (one per domain):
- domHVM_t is an HVM domain that uses a stubdomain device model
diff --git a/tools/flask/policy/policy/modules/xen/xen.if b/tools/flask/policy/policy/modules/xen/xen.if
index 3f58909..2ad11b2 100644
--- a/tools/flask/policy/policy/modules/xen/xen.if
+++ b/tools/flask/policy/policy/modules/xen/xen.if
@@ -9,24 +9,47 @@
# Declare a type as a domain type, and allow basic domain setup
define(`declare_domain', `
type $1, domain_type`'ifelse(`$#', `1', `', `,shift($@)');
+ type $1_channel, event_type;
+ type_transition $1 domain_type:event $1_channel;
allow $1 $1:grant { query setup };
allow $1 $1:mmu { adjust physmap map_read map_write stat pinpage };
allow $1 $1:hvm { getparam setparam };
')

-# create_domain(priv, target)
-# Allow a domain to be created
-define(`create_domain', `
+# 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 scheduler
- unpause getvcpuinfo getvcpuextstate getaddrsize
- getvcpuaffinity };
+ getdomaininfo hypercall setvcpucontext setextvcpucontext
+ scheduler getvcpuinfo getvcpuextstate getaddrsize
+ getvcpuaffinity setvcpuaffinity };
allow $1 $2:security check_context;
allow $1 $2:shadow enable;
allow $1 $2:mmu {map_read map_write adjust memorymap physmap pinpage};
allow $1 $2:grant setup;
- allow $1 $2:hvm { cacheattr getparam hvmctl irqlevel pciroute setparam pcilevel trackdirtyvram };
- allow $1 $2_$1_channel:event create;
+ allow $1 $2:hvm { cacheattr getparam hvmctl irqlevel pciroute sethvmc setparam pcilevel trackdirtyvram };
+')
+
+# 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;
')

# manage_domain(priv, target)
@@ -37,6 +60,15 @@ define(`manage_domain', `
setvcpuaffinity setdomainmaxmem };
')

+# 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 $2:hvm { gethvmc getparam irqlevel };
+ allow $1 $2:mmu { stat pageinfo map_read };
+ allow $1 $2:domain { getaddrsize getvcpucontext getextvcpucontext getvcpuextstate pause destroy };
+')
+
################################################################################
#
# Inter-domain communication
@@ -47,8 +79,6 @@ define(`manage_domain', `
# This allows an event channel to be created from domains with labels
# <source> to <dest> and will label it <chan-label>
define(`create_channel', `
- type $3, event_type;
- type_transition $1 $2:event $3;
allow $1 $3:event { create send status };
allow $3 $2:event { bind };
')
@@ -56,8 +86,8 @@ define(`create_channel', `
# domain_event_comms(dom1, dom2)
# Allow two domain types to communicate using event channels
define(`domain_event_comms', `
- create_channel($1, $2, $1_$2_channel)
- create_channel($2, $1, $2_$1_channel)
+ create_channel($1, $2, $1_channel)
+ create_channel($2, $1, $2_channel)
')

# domain_comms(dom1, dom2)
@@ -72,7 +102,7 @@ define(`domain_comms', `
# Allow a domain types to communicate with others of its type using grants
# and event channels (this includes event channels to DOMID_SELF)
define(`domain_self_comms', `
- create_channel($1, $1, $1_self_channel)
+ create_channel($1, $1, $1_channel)
allow $1 $1:grant { map_read map_write copy unmap };
')

diff --git a/tools/flask/policy/policy/modules/xen/xen.te b/tools/flask/policy/policy/modules/xen/xen.te
index 9550397..1162153 100644
--- a/tools/flask/policy/policy/modules/xen/xen.te
+++ b/tools/flask/policy/policy/modules/xen/xen.te
@@ -90,6 +90,7 @@ create_domain(dom0_t, isolated_domU_t)
manage_domain(dom0_t, isolated_domU_t)
domain_comms(dom0_t, isolated_domU_t)

+# Declare a boolean that denies creation of prot_domU_t domains
gen_bool(prot_doms_locked, false)
declare_domain(prot_domU_t)
if (!prot_doms_locked) {
@@ -111,6 +112,15 @@ manage_domain(dom0_t, dm_dom_t)
domain_comms(dom0_t, dm_dom_t)
device_model(dm_dom_t, domHVM_t)

+# nomigrate_t must be built via the nomigrate_t_building label; once built,
+# dom0 cannot read its memory.
+declare_domain(nomigrate_t)
+declare_build_label(nomigrate_t)
+create_domain_build_label(dom0_t, nomigrate_t)
+manage_domain(dom0_t, nomigrate_t)
+domain_comms(dom0_t, nomigrate_t)
+domain_self_comms(nomigrate_t)
+
###############################################################################
#
# Device delegation
--
1.7.11.7


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
Re: [PATCH 02/19] flask/policy: Add domain relabel example [ In reply to ]
On Fri, 2012-11-16 at 18:28 +0000, Daniel De Graaf wrote:
> This adds the nomigrate_t type to the example FLASK policy which allows
> domains to be created that dom0 cannot access after building.

This is a very cool example of how even dom0's privileges can be
curtailed, I like it!

The fact that the domain can't be migrated is more of a side-effect
though I guess, but I can't really think of a better name (e.g.
"securedom_t" suggests other domains aren't etc...)

I'd ack it but this stuff is all Greek to me ;-)

>
> Example domain configuration snippet:
> seclabel='customer_1:vm_r:nomigrate_t'
> init_seclabel='customer_1:vm_r:nomigrate_t_building'
>
> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> ---
> docs/misc/xsm-flask.txt | 2 +
> tools/flask/policy/policy/modules/xen/xen.if | 56 +++++++++++++++++++++-------
> tools/flask/policy/policy/modules/xen/xen.te | 10 +++++
> 3 files changed, 55 insertions(+), 13 deletions(-)
>
> diff --git a/docs/misc/xsm-flask.txt b/docs/misc/xsm-flask.txt
> index 6b0d327..0778a28 100644
> --- a/docs/misc/xsm-flask.txt
> +++ b/docs/misc/xsm-flask.txt
> @@ -60,6 +60,8 @@ that can be used without dom0 disaggregation. The main types for domUs are:
> - domU_t is a domain that can communicate with any other domU_t
> - isolated_domU_t can only communicate with dom0
> - prot_domU_t is a domain type whose creation can be disabled with a boolean
> + - nomigrate_t is a domain that must be created via the nomigrate_t_building
> + type, and whose memory cannot be read by dom0 once created
>
> HVM domains with stubdomain device models use two types (one per domain):
> - domHVM_t is an HVM domain that uses a stubdomain device model
> diff --git a/tools/flask/policy/policy/modules/xen/xen.if b/tools/flask/policy/policy/modules/xen/xen.if
> index 3f58909..2ad11b2 100644
> --- a/tools/flask/policy/policy/modules/xen/xen.if
> +++ b/tools/flask/policy/policy/modules/xen/xen.if
> @@ -9,24 +9,47 @@
> # Declare a type as a domain type, and allow basic domain setup
> define(`declare_domain', `
> type $1, domain_type`'ifelse(`$#', `1', `', `,shift($@)');
> + type $1_channel, event_type;
> + type_transition $1 domain_type:event $1_channel;
> allow $1 $1:grant { query setup };
> allow $1 $1:mmu { adjust physmap map_read map_write stat pinpage };
> allow $1 $1:hvm { getparam setparam };
> ')
>
> -# create_domain(priv, target)
> -# Allow a domain to be created
> -define(`create_domain', `
> +# 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 scheduler
> - unpause getvcpuinfo getvcpuextstate getaddrsize
> - getvcpuaffinity };
> + getdomaininfo hypercall setvcpucontext setextvcpucontext
> + scheduler getvcpuinfo getvcpuextstate getaddrsize
> + getvcpuaffinity setvcpuaffinity };
> allow $1 $2:security check_context;
> allow $1 $2:shadow enable;
> allow $1 $2:mmu {map_read map_write adjust memorymap physmap pinpage};
> allow $1 $2:grant setup;
> - allow $1 $2:hvm { cacheattr getparam hvmctl irqlevel pciroute setparam pcilevel trackdirtyvram };
> - allow $1 $2_$1_channel:event create;
> + allow $1 $2:hvm { cacheattr getparam hvmctl irqlevel pciroute sethvmc setparam pcilevel trackdirtyvram };
> +')
> +
> +# 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;
> ')
>
> # manage_domain(priv, target)
> @@ -37,6 +60,15 @@ define(`manage_domain', `
> setvcpuaffinity setdomainmaxmem };
> ')
>
> +# 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 $2:hvm { gethvmc getparam irqlevel };
> + allow $1 $2:mmu { stat pageinfo map_read };
> + allow $1 $2:domain { getaddrsize getvcpucontext getextvcpucontext getvcpuextstate pause destroy };
> +')
> +
> ################################################################################
> #
> # Inter-domain communication
> @@ -47,8 +79,6 @@ define(`manage_domain', `
> # This allows an event channel to be created from domains with labels
> # <source> to <dest> and will label it <chan-label>
> define(`create_channel', `
> - type $3, event_type;
> - type_transition $1 $2:event $3;
> allow $1 $3:event { create send status };
> allow $3 $2:event { bind };
> ')
> @@ -56,8 +86,8 @@ define(`create_channel', `
> # domain_event_comms(dom1, dom2)
> # Allow two domain types to communicate using event channels
> define(`domain_event_comms', `
> - create_channel($1, $2, $1_$2_channel)
> - create_channel($2, $1, $2_$1_channel)
> + create_channel($1, $2, $1_channel)
> + create_channel($2, $1, $2_channel)
> ')
>
> # domain_comms(dom1, dom2)
> @@ -72,7 +102,7 @@ define(`domain_comms', `
> # Allow a domain types to communicate with others of its type using grants
> # and event channels (this includes event channels to DOMID_SELF)
> define(`domain_self_comms', `
> - create_channel($1, $1, $1_self_channel)
> + create_channel($1, $1, $1_channel)
> allow $1 $1:grant { map_read map_write copy unmap };
> ')
>
> diff --git a/tools/flask/policy/policy/modules/xen/xen.te b/tools/flask/policy/policy/modules/xen/xen.te
> index 9550397..1162153 100644
> --- a/tools/flask/policy/policy/modules/xen/xen.te
> +++ b/tools/flask/policy/policy/modules/xen/xen.te
> @@ -90,6 +90,7 @@ create_domain(dom0_t, isolated_domU_t)
> manage_domain(dom0_t, isolated_domU_t)
> domain_comms(dom0_t, isolated_domU_t)
>
> +# Declare a boolean that denies creation of prot_domU_t domains
> gen_bool(prot_doms_locked, false)
> declare_domain(prot_domU_t)
> if (!prot_doms_locked) {
> @@ -111,6 +112,15 @@ manage_domain(dom0_t, dm_dom_t)
> domain_comms(dom0_t, dm_dom_t)
> device_model(dm_dom_t, domHVM_t)
>
> +# nomigrate_t must be built via the nomigrate_t_building label; once built,
> +# dom0 cannot read its memory.
> +declare_domain(nomigrate_t)
> +declare_build_label(nomigrate_t)
> +create_domain_build_label(dom0_t, nomigrate_t)
> +manage_domain(dom0_t, nomigrate_t)
> +domain_comms(dom0_t, nomigrate_t)
> +domain_self_comms(nomigrate_t)
> +
> ###############################################################################
> #
> # Device delegation



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
Re: [PATCH 02/19] flask/policy: Add domain relabel example [ In reply to ]
On 11/19/2012 05:46 AM, Ian Campbell wrote:
> On Fri, 2012-11-16 at 18:28 +0000, Daniel De Graaf wrote:
>> This adds the nomigrate_t type to the example FLASK policy which allows
>> domains to be created that dom0 cannot access after building.
>
> This is a very cool example of how even dom0's privileges can be
> curtailed, I like it!
>
> The fact that the domain can't be migrated is more of a side-effect
> though I guess, but I can't really think of a better name (e.g.
> "securedom_t" suggests other domains aren't etc...)

Especially as I have already used some of the other choices (protected,
isolated) for other examples. The inability to migrate actually sums up
the protection this provides: since the only reason dom0 has to read a
domain's memory is to migrate it, preventing migration should (in theory)
prevent that access.

> I'd ack it but this stuff is all Greek to me ;-)

FLASK policies in general tend to be hard to read, especially since using
the M4 macros is almost required to make a sane policy. There is some work
at making a higher-level language for SELinux policy definition, so that
can be applied to Xen at some point. Using sesearch on the Xen policy can
also be useful to see what the result of the definitions is.

>>
>> Example domain configuration snippet:
>> seclabel='customer_1:vm_r:nomigrate_t'
>> init_seclabel='customer_1:vm_r:nomigrate_t_building'
>>
>> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
>> ---
>> docs/misc/xsm-flask.txt | 2 +
>> tools/flask/policy/policy/modules/xen/xen.if | 56 +++++++++++++++++++++-------
>> tools/flask/policy/policy/modules/xen/xen.te | 10 +++++
>> 3 files changed, 55 insertions(+), 13 deletions(-)
>>
>> diff --git a/docs/misc/xsm-flask.txt b/docs/misc/xsm-flask.txt
>> index 6b0d327..0778a28 100644
>> --- a/docs/misc/xsm-flask.txt
>> +++ b/docs/misc/xsm-flask.txt
>> @@ -60,6 +60,8 @@ that can be used without dom0 disaggregation. The main types for domUs are:
>> - domU_t is a domain that can communicate with any other domU_t
>> - isolated_domU_t can only communicate with dom0
>> - prot_domU_t is a domain type whose creation can be disabled with a boolean
>> + - nomigrate_t is a domain that must be created via the nomigrate_t_building
>> + type, and whose memory cannot be read by dom0 once created
>>
>> HVM domains with stubdomain device models use two types (one per domain):
>> - domHVM_t is an HVM domain that uses a stubdomain device model

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel