diff mbox series

[2/2] flask: implement xsm_transtion_running

Message ID 20220420210407.18060-3-dpsmith@apertussolutions.com (mailing list archive)
State Superseded
Headers show
Series Adds starting the idle domain privileged | expand

Commit Message

Daniel P. Smith April 20, 2022, 9:04 p.m. UTC
This commit implements full support for starting the idle domain privileged by
introducing a new flask label xenboot_t which the idle domain is labeled with
at creation.  It then provides the implementation for the XSM hook
xsm_transition_running to relabel the idle domain to the existing xen_t flask
label.

In the reference flask policy a new macro, xen_build_domain(target), is
introduced for creating policies for dom0less/hyperlaunch allowing the
hypervisor to create and assign the necessary resources for domain
construction.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
---
 tools/flask/policy/modules/xen.if      | 6 ++++++
 tools/flask/policy/modules/xen.te      | 1 +
 tools/flask/policy/policy/initial_sids | 1 +
 xen/xsm/flask/hooks.c                  | 6 +++++-
 xen/xsm/flask/policy/initial_sids      | 1 +
 5 files changed, 14 insertions(+), 1 deletion(-)

Comments

Jason Andryuk April 20, 2022, 6:07 p.m. UTC | #1
On Wed, Apr 20, 2022 at 1:03 PM Daniel P. Smith
<dpsmith@apertussolutions.com> wrote:
>
> This commit implements full support for starting the idle domain privileged by
> introducing a new flask label xenboot_t which the idle domain is labeled with
> at creation.  It then provides the implementation for the XSM hook
> xsm_transition_running to relabel the idle domain to the existing xen_t flask
> label.
>
> In the reference flask policy a new macro, xen_build_domain(target), is
> introduced for creating policies for dom0less/hyperlaunch allowing the
> hypervisor to create and assign the necessary resources for domain
> construction.
>
> Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
> ---

> @@ -188,6 +188,7 @@ static int cf_check flask_domain_alloc_security(struct domain *d)
>
>  static void cf_check flask_domain_runtime_security(void)
>  {
> +    struct domain_security_struct *dsec;
>      struct domain *d = current->domain;
>
>      if ( d->domain_id != DOMID_IDLE )
> @@ -198,6 +199,9 @@ static void cf_check flask_domain_runtime_security(void)
>       * set to false for the consistency check(s) in the setup code.
>       */
>      d->is_privileged = false;
> +
> +    dsec = d->ssid;
> +    dsec->sid = SECINITSID_XEN;

I think you also want
   dsec->self_sid = dsec->sid;
so self also changes to xen_t.

Otherwise I think it looks good,

I was wondering if you were going to require xenboot_t -> xen_t
permissions, but manually setting the sid fields side-steps that.
That seems nicer than requiring policy rules for the transition.

Hmmm, cross referencing other flask code, often after assigning
self_sid there is this call to potentially re-calculate it:
    security_transition_sid(dsec->sid, dsec->sid, SECCLASS_DOMAIN,
&dsec->self_sid);

But it isn't used for system domains, so omitting it seems fine.

Regards,
Jason
Daniel P. Smith April 20, 2022, 7:51 p.m. UTC | #2
On 4/20/22 14:07, Jason Andryuk wrote:
> On Wed, Apr 20, 2022 at 1:03 PM Daniel P. Smith
> <dpsmith@apertussolutions.com> wrote:
>>
>> This commit implements full support for starting the idle domain privileged by
>> introducing a new flask label xenboot_t which the idle domain is labeled with
>> at creation.  It then provides the implementation for the XSM hook
>> xsm_transition_running to relabel the idle domain to the existing xen_t flask
>> label.
>>
>> In the reference flask policy a new macro, xen_build_domain(target), is
>> introduced for creating policies for dom0less/hyperlaunch allowing the
>> hypervisor to create and assign the necessary resources for domain
>> construction.
>>
>> Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
>> ---
> 
>> @@ -188,6 +188,7 @@ static int cf_check flask_domain_alloc_security(struct domain *d)
>>
>>  static void cf_check flask_domain_runtime_security(void)
>>  {
>> +    struct domain_security_struct *dsec;
>>      struct domain *d = current->domain;
>>
>>      if ( d->domain_id != DOMID_IDLE )
>> @@ -198,6 +199,9 @@ static void cf_check flask_domain_runtime_security(void)
>>       * set to false for the consistency check(s) in the setup code.
>>       */
>>      d->is_privileged = false;
>> +
>> +    dsec = d->ssid;
>> +    dsec->sid = SECINITSID_XEN;
> 
> I think you also want
>    dsec->self_sid = dsec->sid;
> so self also changes to xen_t.

Erg, thanks for the catch.

> Otherwise I think it looks good,
> 
> I was wondering if you were going to require xenboot_t -> xen_t
> permissions, but manually setting the sid fields side-steps that.
> That seems nicer than requiring policy rules for the transition.

I was considering it but as I was reflecting on the discussions that
were had, this is a one-time, one-way transition. Combine that with the
fact that xenboot_t has to be an initial sid (fixed/permnant type) for
Xen's flask policy, there is no need to require a transition rule in the
policy that can never be changed. And yes, it helps makes things much
simpler.( ^_^)

> Hmmm, cross referencing other flask code, often after assigning
> self_sid there is this call to potentially re-calculate it:
>     security_transition_sid(dsec->sid, dsec->sid, SECCLASS_DOMAIN,
> &dsec->self_sid);
> 
> But it isn't used for system domains, so omitting it seems fine.

Hmm, now you have me concerned about decisions residing in the avc from
accesses made during domain creation. Let me double check that, but I
think it will be needed. I believe the reason it was not needed for the
system domains because prior to this no access decisions were made
before the domains were labeled.

v/r,
dps
diff mbox series

Patch

diff --git a/tools/flask/policy/modules/xen.if b/tools/flask/policy/modules/xen.if
index 5e2aa472b6..4ec676fff1 100644
--- a/tools/flask/policy/modules/xen.if
+++ b/tools/flask/policy/modules/xen.if
@@ -62,6 +62,12 @@  define(`create_domain_common', `
 			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_channel:event create;
+')
+
 # create_domain(priv, target)
 #   Allow a domain to be created directly
 define(`create_domain', `
diff --git a/tools/flask/policy/modules/xen.te b/tools/flask/policy/modules/xen.te
index 3dbf93d2b8..de98206fdd 100644
--- a/tools/flask/policy/modules/xen.te
+++ b/tools/flask/policy/modules/xen.te
@@ -24,6 +24,7 @@  attribute mls_priv;
 ################################################################################
 
 # The hypervisor itself
+type xenboot_t, xen_type, mls_priv;
 type xen_t, xen_type, mls_priv;
 
 # Domain 0
diff --git a/tools/flask/policy/policy/initial_sids b/tools/flask/policy/policy/initial_sids
index 6b7b7eff21..ec729d3ba3 100644
--- a/tools/flask/policy/policy/initial_sids
+++ b/tools/flask/policy/policy/initial_sids
@@ -2,6 +2,7 @@ 
 # objects created before the policy is loaded or for objects that do not have a
 # label defined in some other manner.
 
+sid xenboot gen_context(system_u:system_r:xenboot_t,s0)
 sid xen gen_context(system_u:system_r:xen_t,s0)
 sid dom0 gen_context(system_u:system_r:dom0_t,s0)
 sid domxen gen_context(system_u:system_r:domxen_t,s0)
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 51c896d9f7..7e840af6fc 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -168,7 +168,7 @@  static int cf_check flask_domain_alloc_security(struct domain *d)
     switch ( d->domain_id )
     {
     case DOMID_IDLE:
-        dsec->sid = SECINITSID_XEN;
+        dsec->sid = SECINITSID_XENBOOT;
         break;
     case DOMID_XEN:
         dsec->sid = SECINITSID_DOMXEN;
@@ -188,6 +188,7 @@  static int cf_check flask_domain_alloc_security(struct domain *d)
 
 static void cf_check flask_domain_runtime_security(void)
 {
+    struct domain_security_struct *dsec;
     struct domain *d = current->domain;
 
     if ( d->domain_id != DOMID_IDLE )
@@ -198,6 +199,9 @@  static void cf_check flask_domain_runtime_security(void)
      * set to false for the consistency check(s) in the setup code.
      */
     d->is_privileged = false;
+
+    dsec = d->ssid;
+    dsec->sid = SECINITSID_XEN;
 }
 
 static void cf_check flask_domain_free_security(struct domain *d)
diff --git a/xen/xsm/flask/policy/initial_sids b/xen/xsm/flask/policy/initial_sids
index 7eca70d339..e8b55b8368 100644
--- a/xen/xsm/flask/policy/initial_sids
+++ b/xen/xsm/flask/policy/initial_sids
@@ -3,6 +3,7 @@ 
 #
 # Define initial security identifiers 
 #
+sid xenboot
 sid xen
 sid dom0
 sid domio