[apparmor] [PATCH 23/32] apparmor: provide the ability to boot with a default profile set on init

Seth Arnold seth.arnold at canonical.com
Thu Jan 31 06:27:49 UTC 2013


On Wed, Jan 16, 2013 at 01:28:52PM -0800, John Johansen wrote:
> add the ability to boot with a basic default profile instead of the
> unconfined state.  This provides a way to provide total system confinement
> without having to load policy in the init ramfs.
> 
> The basic default profile can be replaced during early boot to achieve
> system confinement.
> 
> Signed-off-by: John Johansen <john.johansen at canonical.com>
> ---
>  security/apparmor/Kconfig            |   11 +++++++++++
>  security/apparmor/apparmorfs.c       |    4 ++++
>  security/apparmor/include/apparmor.h |    1 +
>  security/apparmor/include/policy.h   |    1 +
>  security/apparmor/lsm.c              |   17 ++++++++++++++---
>  security/apparmor/policy.c           |   21 +++++++++++++++++++++
>  security/apparmor/procattr.c         |    8 +++++---
>  7 files changed, 57 insertions(+), 6 deletions(-)

This was a lot simpler than I expected. Nice.

> diff --git a/security/apparmor/Kconfig b/security/apparmor/Kconfig
> index 9b9013b..1108be7 100644
> --- a/security/apparmor/Kconfig
> +++ b/security/apparmor/Kconfig
> @@ -29,3 +29,14 @@ config SECURITY_APPARMOR_BOOTPARAM_VALUE
>  	  boot.
>  
>  	  If you are unsure how to answer this question, answer 1.
> +
> +config SECURITY_APPARMOR_UNCONFINED_INIT
> +       bool "Set init to unconfined on boot"
> +       depends on SECURITY_APPARMOR
> +       default y
> +       help
> +         This option determines policy behavior during early boot by
> +	 placing the init process in the unconfined state, or the
> +	 'default' profile.
> +
> +	 If you are unsure how to answer this question, answer T.

"answer Y" :)

>  /**
>   * set_init_cxt - set a task context and profile on the first task.
> - *
> - * TODO: allow setting an alternate profile than unconfined
>   */
>  static int __init set_init_cxt(void)
>  {
> @@ -881,7 +884,15 @@ static int __init set_init_cxt(void)
>  	if (!cxt)
>  		return -ENOMEM;
>  
> -	cxt->profile = aa_get_profile(root_ns->unconfined);
> +	if (!aa_g_unconfined_init) {
> +		cxt->profile = aa_setup_default_profile();
> +		if (!cxt->profile) {
> +			aa_free_task_context(cxt);
> +			return -ENOMEM;
> +		}
> +		/* fs setup of default is done in aa_create_aafs() */
> +	} else
> +		cxt->profile = aa_get_profile(root_ns->unconfined);
>  	cred_cxt(cred) = cxt;

What's the consequences of returning -ENOMEM here? I traced it back up
through security_initcall() and gave up when it looked like magic kernel
magic invoked it through magic. :)

Does it fail to boot? (Secure.) Does it boot anyhow?

> +/**
> + * aa_setup_default_profile - create the initial default profile
> + */
> +struct aa_profile *aa_setup_default_profile(void)
> +{
> +	struct aa_profile *profile = aa_alloc_profile("default");
> +	if (!profile)
> +		return NULL;
> +
> +	/* the default profile pretends to be unconfined until it is replaced */
> +	profile->flags = PFLAG_UNCONFINED | PFLAG_IX_ON_NAME_ERROR;
> +
> +	profile->ns = aa_get_namespace(root_ns);

Something seems a bit funny about incrementing the unconfined reference
count to hold the namespace for the default profile which replaces the
unconfined profile. :) (Don't mind me, I just think it's funny.)

> diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
> index 6c93901..39ce95a 100644
> --- a/security/apparmor/procattr.c
> +++ b/security/apparmor/procattr.c
> @@ -41,6 +41,7 @@ int aa_getprocattr(struct aa_profile *profile, char **string)
>  	const char *ns_name = NULL;
>  	struct aa_namespace *ns = profile->ns;
>  	struct aa_namespace *current_ns = __aa_current_profile()->ns;
> +	bool unconfined;
>  	char *s;
>  
>  	if (!aa_ns_visible(current_ns, ns))
> @@ -53,8 +54,9 @@ int aa_getprocattr(struct aa_profile *profile, char **string)
>  	if (ns_len)
>  		ns_len += 4;
>  
> -	/* unconfined profiles don't have a mode string appended */
> -	if (!unconfined(profile))
> +	/* 'unconfined' profile don't have a mode string appended */
> +	unconfined = unconfined(profile) && profile == profile->ns->unconfined;
> +	if (!unconfined)
>  		mode_len = strlen(mode_str) + 3;	/* + 3 for _() */

Oh, this is a bit unfortunate. (Also, && feels wrong, should it be
||?) Can unconfined() be extended to handle this case? Would it be
wrong elsewhere?

>  	name_len = strlen(profile->base.hname);
> @@ -68,7 +70,7 @@ int aa_getprocattr(struct aa_profile *profile, char **string)
>  		sprintf(s, ":%s://", ns_name);
>  		s += ns_len;
>  	}
> -	if (unconfined(profile))
> +	if (unconfined)
>  		/* mode string not being appended */
>  		sprintf(s, "%s\n", profile->base.hname);
>  	else

Thanks
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20130130/9380054f/attachment.pgp>


More information about the AppArmor mailing list