diff mbox series

[security-next,v3,14/29] LSM: Plumb visibility into optional "enabled" state

Message ID 20180925001832.18322-15-keescook@chromium.org (mailing list archive)
State New, archived
Headers show
Series LSM: Explict LSM ordering | expand

Commit Message

Kees Cook Sept. 25, 2018, 12:18 a.m. UTC
In preparation for lifting the "is this LSM enabled?" logic out of the
individual LSMs, pass in any special enabled state tracking (as needed
for SELinux, AppArmor, and LoadPin). This should be an "int" to include
handling any future cases where "enabled" is exposed via sysctl which
has no "bool" type.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 include/linux/lsm_hooks.h | 1 +
 security/apparmor/lsm.c   | 5 +++--
 security/selinux/hooks.c  | 1 +
 3 files changed, 5 insertions(+), 2 deletions(-)

Comments

John Johansen Oct. 1, 2018, 9:18 p.m. UTC | #1
On 09/24/2018 05:18 PM, Kees Cook wrote:
> In preparation for lifting the "is this LSM enabled?" logic out of the
> individual LSMs, pass in any special enabled state tracking (as needed
> for SELinux, AppArmor, and LoadPin). This should be an "int" to include
> handling any future cases where "enabled" is exposed via sysctl which
> has no "bool" type.
> 
> Signed-off-by: Kees Cook <keescook@chromium.org>

Reviewed-by: John Johansen <john.johansen@canonical.com>


> ---
>  include/linux/lsm_hooks.h | 1 +
>  security/apparmor/lsm.c   | 5 +++--
>  security/selinux/hooks.c  | 1 +
>  3 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 5056f7374b3d..2a41e8e6f6e5 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -2044,6 +2044,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
>  struct lsm_info {
>  	const char *name;	/* Populated automatically. */
>  	unsigned long flags;	/* Optional: flags describing LSM */
> +	int *enabled;		/* Optional: NULL means enabled. */
>  	int (*init)(void);
>  };
>  
> diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
> index 4c5f63e9aeba..d03133a267f2 100644
> --- a/security/apparmor/lsm.c
> +++ b/security/apparmor/lsm.c
> @@ -1303,8 +1303,8 @@ bool aa_g_paranoid_load = true;
>  module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO);
>  
>  /* Boot time disable flag */
> -static bool apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
> -module_param_named(enabled, apparmor_enabled, bool, S_IRUGO);
> +static int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
> +module_param_named(enabled, apparmor_enabled, int, 0444);
>  
>  static int __init apparmor_enabled_setup(char *str)
>  {
> @@ -1608,5 +1608,6 @@ static int __init apparmor_init(void)
>  
>  DEFINE_LSM(apparmor)
>  	.flags = LSM_FLAG_LEGACY_MAJOR,
> +	.enabled = &apparmor_enabled,
>  	.init = apparmor_init,
>  END_LSM;
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 615cf6498c0f..3f999ed98cfd 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -7204,6 +7204,7 @@ void selinux_complete_init(void)
>     all processes and objects when they are created. */
>  DEFINE_LSM(selinux)
>  	.flags = LSM_FLAG_LEGACY_MAJOR,
> +	.enabled = &selinux_enabled,
>  	.init = selinux_init,
>  END_LSM;
>  
>
James Morris Oct. 1, 2018, 9:47 p.m. UTC | #2
On Mon, 24 Sep 2018, Kees Cook wrote:

> In preparation for lifting the "is this LSM enabled?" logic out of the
> individual LSMs, pass in any special enabled state tracking (as needed
> for SELinux, AppArmor, and LoadPin). This should be an "int" to include
> handling any future cases where "enabled" is exposed via sysctl which
> has no "bool" type.
> 
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  include/linux/lsm_hooks.h | 1 +
>  security/apparmor/lsm.c   | 5 +++--
>  security/selinux/hooks.c  | 1 +
>  3 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 5056f7374b3d..2a41e8e6f6e5 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -2044,6 +2044,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
>  struct lsm_info {
>  	const char *name;	/* Populated automatically. */
>  	unsigned long flags;	/* Optional: flags describing LSM */
> +	int *enabled;		/* Optional: NULL means enabled. */

This seems potentially confusing.

Perhaps initialize 'enabled' to a default int pointer, like:

	static int lsm_default_enabled = 1;

Then,

	DEFINE_LSM(foobar)
	flags = LSM_FLAG_LEGACY_MAJOR,
	.enabled = &lsm_default_enabled,
	.init = foobar_init,
	END_LSM;



>  	int (*init)(void);
>  };
>  
> diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
> index 4c5f63e9aeba..d03133a267f2 100644
> --- a/security/apparmor/lsm.c
> +++ b/security/apparmor/lsm.c
> @@ -1303,8 +1303,8 @@ bool aa_g_paranoid_load = true;
>  module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO);
>  
>  /* Boot time disable flag */
> -static bool apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
> -module_param_named(enabled, apparmor_enabled, bool, S_IRUGO);
> +static int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
> +module_param_named(enabled, apparmor_enabled, int, 0444);
>  
>  static int __init apparmor_enabled_setup(char *str)
>  {
> @@ -1608,5 +1608,6 @@ static int __init apparmor_init(void)
>  
>  DEFINE_LSM(apparmor)
>  	.flags = LSM_FLAG_LEGACY_MAJOR,
> +	.enabled = &apparmor_enabled,
>  	.init = apparmor_init,
>  END_LSM;
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 615cf6498c0f..3f999ed98cfd 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -7204,6 +7204,7 @@ void selinux_complete_init(void)
>     all processes and objects when they are created. */
>  DEFINE_LSM(selinux)
>  	.flags = LSM_FLAG_LEGACY_MAJOR,
> +	.enabled = &selinux_enabled,
>  	.init = selinux_init,
>  END_LSM;
>  
>
Kees Cook Oct. 1, 2018, 9:56 p.m. UTC | #3
On Mon, Oct 1, 2018 at 2:47 PM, James Morris <jmorris@namei.org> wrote:
> On Mon, 24 Sep 2018, Kees Cook wrote:
>
>> In preparation for lifting the "is this LSM enabled?" logic out of the
>> individual LSMs, pass in any special enabled state tracking (as needed
>> for SELinux, AppArmor, and LoadPin). This should be an "int" to include
>> handling any future cases where "enabled" is exposed via sysctl which
>> has no "bool" type.
>>
>> Signed-off-by: Kees Cook <keescook@chromium.org>
>> ---
>>  include/linux/lsm_hooks.h | 1 +
>>  security/apparmor/lsm.c   | 5 +++--
>>  security/selinux/hooks.c  | 1 +
>>  3 files changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
>> index 5056f7374b3d..2a41e8e6f6e5 100644
>> --- a/include/linux/lsm_hooks.h
>> +++ b/include/linux/lsm_hooks.h
>> @@ -2044,6 +2044,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
>>  struct lsm_info {
>>       const char *name;       /* Populated automatically. */
>>       unsigned long flags;    /* Optional: flags describing LSM */
>> +     int *enabled;           /* Optional: NULL means enabled. */
>
> This seems potentially confusing.
>
> Perhaps initialize 'enabled' to a default int pointer, like:
>
>         static int lsm_default_enabled = 1;
>
> Then,
>
>         DEFINE_LSM(foobar)
>         flags = LSM_FLAG_LEGACY_MAJOR,
>         .enabled = &lsm_default_enabled,
>         .init = foobar_init,
>         END_LSM;

The reason I didn't do this is because there are only two LSMs that
expose this "enabled" variable, so I didn't like making the other LSMs
have to declare this. Internally, though, this is exactly what the
infrastructure does: if it finds a NULL, it aims it at
&lsm_default_enabled (in a later patch).

However, it seems more discussion is needed on the "enable" bit of
this, so I'll reply to John in a moment...

-Kees
John Johansen Oct. 1, 2018, 10:20 p.m. UTC | #4
On 10/01/2018 02:56 PM, Kees Cook wrote:
> On Mon, Oct 1, 2018 at 2:47 PM, James Morris <jmorris@namei.org> wrote:
>> On Mon, 24 Sep 2018, Kees Cook wrote:
>>
>>> In preparation for lifting the "is this LSM enabled?" logic out of the
>>> individual LSMs, pass in any special enabled state tracking (as needed
>>> for SELinux, AppArmor, and LoadPin). This should be an "int" to include
>>> handling any future cases where "enabled" is exposed via sysctl which
>>> has no "bool" type.
>>>
>>> Signed-off-by: Kees Cook <keescook@chromium.org>
>>> ---
>>>  include/linux/lsm_hooks.h | 1 +
>>>  security/apparmor/lsm.c   | 5 +++--
>>>  security/selinux/hooks.c  | 1 +
>>>  3 files changed, 5 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
>>> index 5056f7374b3d..2a41e8e6f6e5 100644
>>> --- a/include/linux/lsm_hooks.h
>>> +++ b/include/linux/lsm_hooks.h
>>> @@ -2044,6 +2044,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
>>>  struct lsm_info {
>>>       const char *name;       /* Populated automatically. */
>>>       unsigned long flags;    /* Optional: flags describing LSM */
>>> +     int *enabled;           /* Optional: NULL means enabled. */
>>
>> This seems potentially confusing.
>>
>> Perhaps initialize 'enabled' to a default int pointer, like:
>>
>>         static int lsm_default_enabled = 1;
>>
>> Then,
>>
>>         DEFINE_LSM(foobar)
>>         flags = LSM_FLAG_LEGACY_MAJOR,
>>         .enabled = &lsm_default_enabled,
>>         .init = foobar_init,
>>         END_LSM;
> 
> The reason I didn't do this is because there are only two LSMs that
> expose this "enabled" variable, so I didn't like making the other LSMs
> have to declare this. Internally, though, this is exactly what the
> infrastructure does: if it finds a NULL, it aims it at
> &lsm_default_enabled (in a later patch).
> 
> However, it seems more discussion is needed on the "enable" bit of
> this, so I'll reply to John in a moment...
> 
fwiw the apparmor.enabled config is really only a meant to be used to
disable apparmor. I'd drop it entirely except its part of the userspace
api now and needs to show up in

  /sys/module/apparmor/parameters/enabled
Kees Cook Oct. 1, 2018, 10:29 p.m. UTC | #5
On Mon, Oct 1, 2018 at 3:20 PM, John Johansen
<john.johansen@canonical.com> wrote:
> On 10/01/2018 02:56 PM, Kees Cook wrote:
>> On Mon, Oct 1, 2018 at 2:47 PM, James Morris <jmorris@namei.org> wrote:
>>> On Mon, 24 Sep 2018, Kees Cook wrote:
>>>
>>>> In preparation for lifting the "is this LSM enabled?" logic out of the
>>>> individual LSMs, pass in any special enabled state tracking (as needed
>>>> for SELinux, AppArmor, and LoadPin). This should be an "int" to include
>>>> handling any future cases where "enabled" is exposed via sysctl which
>>>> has no "bool" type.
>>>>
>>>> Signed-off-by: Kees Cook <keescook@chromium.org>
>>>> ---
>>>>  include/linux/lsm_hooks.h | 1 +
>>>>  security/apparmor/lsm.c   | 5 +++--
>>>>  security/selinux/hooks.c  | 1 +
>>>>  3 files changed, 5 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
>>>> index 5056f7374b3d..2a41e8e6f6e5 100644
>>>> --- a/include/linux/lsm_hooks.h
>>>> +++ b/include/linux/lsm_hooks.h
>>>> @@ -2044,6 +2044,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
>>>>  struct lsm_info {
>>>>       const char *name;       /* Populated automatically. */
>>>>       unsigned long flags;    /* Optional: flags describing LSM */
>>>> +     int *enabled;           /* Optional: NULL means enabled. */
>>>
>>> This seems potentially confusing.
>>>
>>> Perhaps initialize 'enabled' to a default int pointer, like:
>>>
>>>         static int lsm_default_enabled = 1;
>>>
>>> Then,
>>>
>>>         DEFINE_LSM(foobar)
>>>         flags = LSM_FLAG_LEGACY_MAJOR,
>>>         .enabled = &lsm_default_enabled,
>>>         .init = foobar_init,
>>>         END_LSM;
>>
>> The reason I didn't do this is because there are only two LSMs that
>> expose this "enabled" variable, so I didn't like making the other LSMs
>> have to declare this. Internally, though, this is exactly what the
>> infrastructure does: if it finds a NULL, it aims it at
>> &lsm_default_enabled (in a later patch).
>>
>> However, it seems more discussion is needed on the "enable" bit of
>> this, so I'll reply to John in a moment...
>>
> fwiw the apparmor.enabled config is really only a meant to be used to
> disable apparmor. I'd drop it entirely except its part of the userspace
> api now and needs to show up in
>
>   /sys/module/apparmor/parameters/enabled

Showing the enabled-ness there can be wired up. What should happen if
someone sets apparmor.enabled=0/1 in new-series-world? (See other
thread...)

-Kees
John Johansen Oct. 1, 2018, 10:53 p.m. UTC | #6
On 10/01/2018 03:29 PM, Kees Cook wrote:
> On Mon, Oct 1, 2018 at 3:20 PM, John Johansen
> <john.johansen@canonical.com> wrote:
>> On 10/01/2018 02:56 PM, Kees Cook wrote:
>>> On Mon, Oct 1, 2018 at 2:47 PM, James Morris <jmorris@namei.org> wrote:
>>>> On Mon, 24 Sep 2018, Kees Cook wrote:
>>>>
>>>>> In preparation for lifting the "is this LSM enabled?" logic out of the
>>>>> individual LSMs, pass in any special enabled state tracking (as needed
>>>>> for SELinux, AppArmor, and LoadPin). This should be an "int" to include
>>>>> handling any future cases where "enabled" is exposed via sysctl which
>>>>> has no "bool" type.
>>>>>
>>>>> Signed-off-by: Kees Cook <keescook@chromium.org>
>>>>> ---
>>>>>  include/linux/lsm_hooks.h | 1 +
>>>>>  security/apparmor/lsm.c   | 5 +++--
>>>>>  security/selinux/hooks.c  | 1 +
>>>>>  3 files changed, 5 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
>>>>> index 5056f7374b3d..2a41e8e6f6e5 100644
>>>>> --- a/include/linux/lsm_hooks.h
>>>>> +++ b/include/linux/lsm_hooks.h
>>>>> @@ -2044,6 +2044,7 @@ extern void security_add_hooks(struct security_hook_list *hooks, int count,
>>>>>  struct lsm_info {
>>>>>       const char *name;       /* Populated automatically. */
>>>>>       unsigned long flags;    /* Optional: flags describing LSM */
>>>>> +     int *enabled;           /* Optional: NULL means enabled. */
>>>>
>>>> This seems potentially confusing.
>>>>
>>>> Perhaps initialize 'enabled' to a default int pointer, like:
>>>>
>>>>         static int lsm_default_enabled = 1;
>>>>
>>>> Then,
>>>>
>>>>         DEFINE_LSM(foobar)
>>>>         flags = LSM_FLAG_LEGACY_MAJOR,
>>>>         .enabled = &lsm_default_enabled,
>>>>         .init = foobar_init,
>>>>         END_LSM;
>>>
>>> The reason I didn't do this is because there are only two LSMs that
>>> expose this "enabled" variable, so I didn't like making the other LSMs
>>> have to declare this. Internally, though, this is exactly what the
>>> infrastructure does: if it finds a NULL, it aims it at
>>> &lsm_default_enabled (in a later patch).
>>>
>>> However, it seems more discussion is needed on the "enable" bit of
>>> this, so I'll reply to John in a moment...
>>>
>> fwiw the apparmor.enabled config is really only a meant to be used to
>> disable apparmor. I'd drop it entirely except its part of the userspace
>> api now and needs to show up in
>>
>>   /sys/module/apparmor/parameters/enabled
> 
> Showing the enabled-ness there can be wired up. What should happen if
> someone sets apparmor.enabled=0/1 in new-series-world? (See other
> thread...)
> 
I am open to either just making apparmor=0/apparmor.enabled=0 a means
of only disabling apparmor, thats how it is currently used. Or even
potentially getting rid of it as an available kernel boot config
parameter and running with just lsm.enabled/disabled.

The important bit that applications are relying on is having
  /sys/module/apparmor/parameters/enabled

set to the the correct value.
diff mbox series

Patch

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 5056f7374b3d..2a41e8e6f6e5 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2044,6 +2044,7 @@  extern void security_add_hooks(struct security_hook_list *hooks, int count,
 struct lsm_info {
 	const char *name;	/* Populated automatically. */
 	unsigned long flags;	/* Optional: flags describing LSM */
+	int *enabled;		/* Optional: NULL means enabled. */
 	int (*init)(void);
 };
 
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 4c5f63e9aeba..d03133a267f2 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1303,8 +1303,8 @@  bool aa_g_paranoid_load = true;
 module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO);
 
 /* Boot time disable flag */
-static bool apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
-module_param_named(enabled, apparmor_enabled, bool, S_IRUGO);
+static int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
+module_param_named(enabled, apparmor_enabled, int, 0444);
 
 static int __init apparmor_enabled_setup(char *str)
 {
@@ -1608,5 +1608,6 @@  static int __init apparmor_init(void)
 
 DEFINE_LSM(apparmor)
 	.flags = LSM_FLAG_LEGACY_MAJOR,
+	.enabled = &apparmor_enabled,
 	.init = apparmor_init,
 END_LSM;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 615cf6498c0f..3f999ed98cfd 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -7204,6 +7204,7 @@  void selinux_complete_init(void)
    all processes and objects when they are created. */
 DEFINE_LSM(selinux)
 	.flags = LSM_FLAG_LEGACY_MAJOR,
+	.enabled = &selinux_enabled,
 	.init = selinux_init,
 END_LSM;