From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Daniel De Graaf <dgdegra@tycho.nsa.gov>, xen-devel@lists.xenproject.org
Cc: julien.grall@linaro.org, wei.liu2@citrix.com, ian.campbell@citrix.com
Subject: Re: [PATCH v5] flask: create unified "flask=" boot parameter
Date: Mon, 9 Mar 2015 17:31:37 +0000 [thread overview]
Message-ID: <54FDD8F9.9020501@citrix.com> (raw)
In-Reply-To: <1425920559-19570-1-git-send-email-dgdegra@tycho.nsa.gov>
On 09/03/15 17:02, Daniel De Graaf wrote:
> This unifies the flask_enforcing and flask_enabled boot parameters into
> a single parameter with additional states. Defined options are:
>
> enforcing - require policy to be loaded at boot time and enforce it
> permissive - a missing or broken policy does not panic
> disabled - revert to dummy (no XSM) policy. Was flask_enabled=0
> late - bootloader policy is not used; later loadpolicy is enforcing
>
> The default mode remains "permissive" and the flask_enforcing boot
> parameter is retained for compatibility. If flask_enforcing=1 is
> specified and flask= is not, the bootloader policy will be loaded in
> enforcing mode if present, but errors will disable access controls until
> a successful loadpolicy instead of causing a panic at boot.
>
> Suggested-by: Julien Grall <julien.grall@linaro.org>
> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Bonus - we gain more command line documentation!
> ---
> Changes from v4:
> - Use enum and bool_t for parameter globals
> - Remove duplication of flask=force/enforcing
> - Move panic out of command line parsing so it is visible
>
> ---
> docs/man/xl.pod.1 | 4 ++--
> docs/misc/xen-command-line.markdown | 30 +++++++++++++++++++++++++-----
> docs/misc/xsm-flask.txt | 29 -----------------------------
> xen/xsm/flask/flask_op.c | 34 ++++++++++++++++++++++++++++++----
> xen/xsm/flask/hooks.c | 32 +++++++++++++++++++++++---------
> xen/xsm/flask/include/avc.h | 2 +-
> xen/xsm/flask/include/security.h | 10 +++++++++-
> 7 files changed, 90 insertions(+), 51 deletions(-)
>
> diff --git a/docs/man/xl.pod.1 b/docs/man/xl.pod.1
> index cd80ffc..198ee2b 100644
> --- a/docs/man/xl.pod.1
> +++ b/docs/man/xl.pod.1
> @@ -1441,8 +1441,8 @@ Determine if the FLASK security module is loaded and enforcing its policy.
> =item B<setenforce> I<1|0|Enforcing|Permissive>
>
> Enable or disable enforcing of the FLASK access controls. The default is
> -permissive and can be changed using the flask_enforcing option on the
> -hypervisor's command line.
> +permissive, but this can be changed to enforcing by specifying "flask=enforcing"
> +or "flask=late" on the hypervisor's command line.
>
> =item B<loadpolicy> I<policy-file>
>
> diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
> index e125212..5044da1 100644
> --- a/docs/misc/xen-command-line.markdown
> +++ b/docs/misc/xen-command-line.markdown
> @@ -638,11 +638,31 @@ hardware domain is architecture dependent.
> Note that specifying zero as domU value means zero, while for dom0 it means
> to use the default.
>
> -### flask\_enabled
> -> `= <integer>`
> -
> -### flask\_enforcing
> -> `= <integer>`
> +### flask
> +> `= permissive | enforcing | late | disabled`
> +
> +> Default: `permissive`
> +
> +Specify how the FLASK security server should be configured. This option is only
> +available if the hypervisor was compiled with XSM support (which can be enabled
> +by setting XSM\_ENABLE = y in .config).
> +
> +* `permissive`: This is intended for development and is not suitable for use
> + with untrusted guests. If a policy is provided by the bootloader, it will be
> + loaded; errors will be reported to the ring buffer but will not prevent
> + booting. The policy can be changed to enforcing mode using "xl setenforce".
> +* `enforcing`: This requires a security policy to be provided by the bootloader
> + and will enter enforcing mode prior to the creation of domain 0. If a valid
> + policy is not provided, the hypervisor will not continue booting.
> +* `late`: This disables loading of the security policy from the bootloader.
> + FLASK will be enabled but will not enforce access controls until a policy is
> + loaded by a domain using "xl loadpolicy". Once a policy is loaded, FLASK will
> + run in enforcing mode unless "xl setenforce" has changed that setting.
> +* `disabled`: This causes the XSM framework to revert to the dummy module. The
> + dummy module provides the same security policy as is used when compiling the
> + hypervisor without support for XSM. The xsm\_op hypercall can also be used to
> + switch to this mode after boot, but there is no way to re-enable FLASK once
> + the dummy module is loaded.
>
> ### font
> > `= <height>` where height is `8x8 | 8x14 | 8x16`
> diff --git a/docs/misc/xsm-flask.txt b/docs/misc/xsm-flask.txt
> index 9559028..ab05913 100644
> --- a/docs/misc/xsm-flask.txt
> +++ b/docs/misc/xsm-flask.txt
> @@ -396,32 +396,3 @@ the ranges being denied to more easily determine what resources are required.
> When running in permissive mode, only the first denial of a given
> source/destination is printed to the log, so labeling devices using this method
> may require multiple passes to find all required ranges.
> -
> -Additional notes on XSM:FLASK
> ------------------------------
> -
> -1) xen command line parameters
> -
> - a) flask_enforcing
> -
> - The default value for flask_enforcing is '0'. This parameter causes the
> - platform to boot in permissive mode which means that the policy is loaded
> - but not enforced. This mode is often helpful for developing new systems
> - and policies as the policy violations are reported on the xen console and
> - may be viewed in dom0 through 'xl dmesg'.
> -
> - To boot the platform into enforcing mode, which means that the policy is
> - loaded and enforced, append 'flask_enforcing=1' on the grub line.
> -
> - This parameter may also be changed through the flask hypercall.
> -
> - b) flask_enabled
> -
> - The default value for flask_enabled is '1'. This parameter causes the
> - platform to enable the FLASK security module under the XSM framework.
> - The parameter may be enabled/disabled only once per boot. If the parameter
> - is set to '0', only a reboot can re-enable flask. When flask_enabled is '0'
> - the DUMMY module is enforced.
> -
> - This parameter may also be changed through the flask hypercall. But may
> - only be performed once per boot.
> diff --git a/xen/xsm/flask/flask_op.c b/xen/xsm/flask/flask_op.c
> index 0e89360..84c7fec 100644
> --- a/xen/xsm/flask/flask_op.c
> +++ b/xen/xsm/flask/flask_op.c
> @@ -24,11 +24,12 @@
> #define _copy_to_guest copy_to_guest
> #define _copy_from_guest copy_from_guest
>
> -int flask_enforcing = 0;
> -integer_param("flask_enforcing", flask_enforcing);
> +enum flask_bootparam_t __read_mostly flask_bootparam = FLASK_BOOTPARAM_PERMISSIVE;
> +static void parse_flask_param(char *s);
> +custom_param("flask", parse_flask_param);
>
> -int flask_enabled = 1;
> -integer_param("flask_enabled", flask_enabled);
> +bool_t __read_mostly flask_enforcing = 0;
> +boolean_param("flask_enforcing", flask_enforcing);
>
> #define MAX_POLICY_SIZE 0x4000000
>
> @@ -60,6 +61,26 @@ extern int ss_initialized;
>
> extern struct xsm_operations *original_ops;
>
> +static void __init parse_flask_param(char *s)
> +{
> + if ( !strcmp(s, "enforcing") )
> + {
> + flask_enforcing = 1;
> + flask_bootparam = FLASK_BOOTPARAM_ENFORCING;
> + }
> + else if ( !strcmp(s, "late") )
> + {
> + flask_enforcing = 1;
> + flask_bootparam = FLASK_BOOTPARAM_LATELOAD;
> + }
> + else if ( !strcmp(s, "disabled") )
> + flask_bootparam = FLASK_BOOTPARAM_DISABLED;
> + else if ( !strcmp(s, "permissive") )
> + flask_bootparam = FLASK_BOOTPARAM_PERMISSIVE;
> + else
> + flask_bootparam = FLASK_BOOTPARAM_INVALID;
> +}
> +
> static int domain_has_security(struct domain *d, u32 perms)
> {
> struct domain_security_struct *dsec;
> @@ -502,6 +523,7 @@ static int flask_security_load(struct xen_flask_load *load)
> {
> int ret;
> void *buf = NULL;
> + bool_t is_reload = ss_initialized;
>
> ret = domain_has_security(current->domain, SECURITY__LOAD_POLICY);
> if ( ret )
> @@ -526,6 +548,10 @@ static int flask_security_load(struct xen_flask_load *load)
> if ( ret )
> goto out;
>
> + if ( !is_reload )
> + printk(XENLOG_INFO "Flask: Policy loaded, continuing in %s mode.\n",
> + flask_enforcing ? "enforcing" : "permissive");
> +
> xfree(bool_pending_values);
> bool_pending_values = NULL;
> ret = 0;
> diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
> index dad5deb..05dafed 100644
> --- a/xen/xsm/flask/hooks.c
> +++ b/xen/xsm/flask/hooks.c
> @@ -1628,15 +1628,23 @@ static struct xsm_operations flask_ops = {
>
> static __init void flask_init(void)
> {
> - int ret = 0;
> + int ret = -ENOENT;
>
> - if ( !flask_enabled )
> + switch ( flask_bootparam )
> {
> - printk("Flask: Disabled at boot.\n");
> + case FLASK_BOOTPARAM_DISABLED:
> + printk(XENLOG_INFO "Flask: Disabled at boot.\n");
> return;
> - }
>
> - printk("Flask: Initializing.\n");
> + case FLASK_BOOTPARAM_PERMISSIVE:
> + case FLASK_BOOTPARAM_ENFORCING:
> + case FLASK_BOOTPARAM_LATELOAD:
> + break;
> +
> + case FLASK_BOOTPARAM_INVALID:
> + default:
> + panic("Flask: Invalid value for flask= boot parameter.\n");
> + }
>
> avc_init();
>
> @@ -1644,12 +1652,18 @@ static __init void flask_init(void)
> if ( register_xsm(&flask_ops) )
> panic("Flask: Unable to register with XSM");
>
> - ret = security_load_policy(policy_buffer, policy_size);
> + if ( policy_size && flask_bootparam != FLASK_BOOTPARAM_LATELOAD )
> + ret = security_load_policy(policy_buffer, policy_size);
> +
> + if ( ret && flask_bootparam == FLASK_BOOTPARAM_ENFORCING )
> + panic("Unable to load FLASK policy");
>
> - if ( flask_enforcing )
> - printk("Flask: Starting in enforcing mode.\n");
> + if ( ret )
> + printk(XENLOG_INFO "Flask: Access controls disabled until policy is loaded.\n");
> + else if ( flask_enforcing )
> + printk(XENLOG_INFO "Flask: Starting in enforcing mode.\n");
> else
> - printk("Flask: Starting in permissive mode.\n");
> + printk(XENLOG_INFO "Flask: Starting in permissive mode.\n");
> }
>
> xsm_initcall(flask_init);
> diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h
> index a00a6eb..c7a99fc 100644
> --- a/xen/xsm/flask/include/avc.h
> +++ b/xen/xsm/flask/include/avc.h
> @@ -17,7 +17,7 @@
> #include "av_permissions.h"
> #include "security.h"
>
> -extern int flask_enforcing;
> +extern bool_t flask_enforcing;
>
> /*
> * An entry in the AVC.
> diff --git a/xen/xsm/flask/include/security.h b/xen/xsm/flask/include/security.h
> index dea0143..d07bae0 100644
> --- a/xen/xsm/flask/include/security.h
> +++ b/xen/xsm/flask/include/security.h
> @@ -35,7 +35,15 @@
> #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
> #define POLICYDB_VERSION_MAX POLICYDB_VERSION_BOUNDARY
>
> -extern int flask_enabled;
> +enum flask_bootparam_t {
> + FLASK_BOOTPARAM_PERMISSIVE,
> + FLASK_BOOTPARAM_ENFORCING,
> + FLASK_BOOTPARAM_LATELOAD,
> + FLASK_BOOTPARAM_DISABLED,
> + FLASK_BOOTPARAM_INVALID,
> +};
> +
> +extern enum flask_bootparam_t flask_bootparam;
> extern int flask_mls_enabled;
>
> int security_load_policy(void * data, size_t len);
prev parent reply other threads:[~2015-03-09 17:31 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-09 17:02 [PATCH v5] flask: create unified "flask=" boot parameter Daniel De Graaf
2015-03-09 17:31 ` Andrew Cooper [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54FDD8F9.9020501@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=dgdegra@tycho.nsa.gov \
--cc=ian.campbell@citrix.com \
--cc=julien.grall@linaro.org \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.