Re: [PATCH v5 1/1] security: Add mechanism to safely (un)load LSMs after boot time

2018-04-11 Thread Paul Moore
On Wed, Apr 11, 2018 at 10:17 AM, Stephen Smalley  wrote:
> On 04/10/2018 05:24 PM, Sargun Dhillon wrote:
>> On Sun, Apr 8, 2018 at 10:25 PM, Tetsuo Handa
>>  wrote:
>>> Sargun Dhillon wrote:
>   Remove SECURITY_HOOK_COUNT and "struct security_hook_list"->owner and
>   the exception in randomize_layout_plugin.c because preventing module
>   unloading won't work as expected.
>

 Rather than completely removing the unloading code, might it make
 sense to add a BUG_ON or WARN_ON, in security_delete_hooks if
 allow_unload_module is false, and owner is not NULL?
>>>
>>> Do we need to check ->owner != NULL? Although it will be true that
>>> SELinux's ->owner == NULL and LKM-based LSM module's ->owner != NULL,
>>> I think we unregister SELinux before setting allow_unload_module to false.
>>> Thus, rejecting delete_security_hooks() if allow_unload_module == false will
>>> be sufficient. SELinux might want to call panic() if delete_security_hooks()
>>> did not unregister due to allow_unload_module == false. Also,
>>> allow_unload_module would be renamed to allow_unregister_module.
>>>
>>> By the way, please don't use BUG_ON() or WARN_ON() because syzbot would hit
>>> and call panic() because syzbot runs tests with panic_on_warn == true.
>>
>> I think my primary question is for the SELinux folks -- what do you
>> think the behaviour should be? If allow_unload_modules /
>> allow_unregister_module is set, do you want to be able to call
>> security_delete_hooks? What do you think the right
>> action should be if it fails?
>
> The one that avoids breakage for existing users ;)
>
> I personally am in favor of killing SELinux support for runtime disable aka
> CONFIG_SECURITY_SELINUX_DISABLE; the only reason it exists is that Red Hat
> originally insisted that bootloader configuration is too painful to 
> modify/update on
> certain platforms and therefore the selinux=0 boot parameter is insufficient
> as a mechanism for disabling SELinux.

I too would like to remove the SELinux runtime disable code, and we
have looked at it briefly but there are a number of
userspace/bootloader upgrade concerns that need to be addressed first
(some of the issues have been captured in the BZ linked below).
Unfortunately it isn't as trivial a chance as it would initially
appear.

* https://bugzilla.redhat.com/show_bug.cgi?id=1430944

> However, we can't break existing users.  Userspace should still attempt to 
> proceed
> even if runtime disable fails, just with SELinux left in permissive mode and 
> no
> policy loaded.  That generally should work, but does retain the performance 
> overhead
> of the SELinux hook function processing, unlike a real disable.
>
> I don't think we particularly care about allow_unload_modules / 
> allow_unregister_module
> since there is no existing userspace or configurations relying on it.

-- 
paul moore
www.paul-moore.com


Re: [PATCH v5 1/1] security: Add mechanism to safely (un)load LSMs after boot time

2018-04-11 Thread Paul Moore
On Wed, Apr 11, 2018 at 10:17 AM, Stephen Smalley  wrote:
> On 04/10/2018 05:24 PM, Sargun Dhillon wrote:
>> On Sun, Apr 8, 2018 at 10:25 PM, Tetsuo Handa
>>  wrote:
>>> Sargun Dhillon wrote:
>   Remove SECURITY_HOOK_COUNT and "struct security_hook_list"->owner and
>   the exception in randomize_layout_plugin.c because preventing module
>   unloading won't work as expected.
>

 Rather than completely removing the unloading code, might it make
 sense to add a BUG_ON or WARN_ON, in security_delete_hooks if
 allow_unload_module is false, and owner is not NULL?
>>>
>>> Do we need to check ->owner != NULL? Although it will be true that
>>> SELinux's ->owner == NULL and LKM-based LSM module's ->owner != NULL,
>>> I think we unregister SELinux before setting allow_unload_module to false.
>>> Thus, rejecting delete_security_hooks() if allow_unload_module == false will
>>> be sufficient. SELinux might want to call panic() if delete_security_hooks()
>>> did not unregister due to allow_unload_module == false. Also,
>>> allow_unload_module would be renamed to allow_unregister_module.
>>>
>>> By the way, please don't use BUG_ON() or WARN_ON() because syzbot would hit
>>> and call panic() because syzbot runs tests with panic_on_warn == true.
>>
>> I think my primary question is for the SELinux folks -- what do you
>> think the behaviour should be? If allow_unload_modules /
>> allow_unregister_module is set, do you want to be able to call
>> security_delete_hooks? What do you think the right
>> action should be if it fails?
>
> The one that avoids breakage for existing users ;)
>
> I personally am in favor of killing SELinux support for runtime disable aka
> CONFIG_SECURITY_SELINUX_DISABLE; the only reason it exists is that Red Hat
> originally insisted that bootloader configuration is too painful to 
> modify/update on
> certain platforms and therefore the selinux=0 boot parameter is insufficient
> as a mechanism for disabling SELinux.

I too would like to remove the SELinux runtime disable code, and we
have looked at it briefly but there are a number of
userspace/bootloader upgrade concerns that need to be addressed first
(some of the issues have been captured in the BZ linked below).
Unfortunately it isn't as trivial a chance as it would initially
appear.

* https://bugzilla.redhat.com/show_bug.cgi?id=1430944

> However, we can't break existing users.  Userspace should still attempt to 
> proceed
> even if runtime disable fails, just with SELinux left in permissive mode and 
> no
> policy loaded.  That generally should work, but does retain the performance 
> overhead
> of the SELinux hook function processing, unlike a real disable.
>
> I don't think we particularly care about allow_unload_modules / 
> allow_unregister_module
> since there is no existing userspace or configurations relying on it.

-- 
paul moore
www.paul-moore.com


Re: [PATCH v5 1/1] security: Add mechanism to safely (un)load LSMs after boot time

2018-04-11 Thread Stephen Smalley
On 04/10/2018 05:24 PM, Sargun Dhillon wrote:
> On Sun, Apr 8, 2018 at 10:25 PM, Tetsuo Handa
>  wrote:
>> Sargun Dhillon wrote:
   Remove SECURITY_HOOK_COUNT and "struct security_hook_list"->owner and
   the exception in randomize_layout_plugin.c because preventing module
   unloading won't work as expected.

>>>
>>> Rather than completely removing the unloading code, might it make
>>> sense to add a BUG_ON or WARN_ON, in security_delete_hooks if
>>> allow_unload_module is false, and owner is not NULL?
>>
>> Do we need to check ->owner != NULL? Although it will be true that
>> SELinux's ->owner == NULL and LKM-based LSM module's ->owner != NULL,
>> I think we unregister SELinux before setting allow_unload_module to false.
>> Thus, rejecting delete_security_hooks() if allow_unload_module == false will
>> be sufficient. SELinux might want to call panic() if delete_security_hooks()
>> did not unregister due to allow_unload_module == false. Also,
>> allow_unload_module would be renamed to allow_unregister_module.
>>
>> By the way, please don't use BUG_ON() or WARN_ON() because syzbot would hit
>> and call panic() because syzbot runs tests with panic_on_warn == true.
> 
> I think my primary question is for the SELinux folks -- what do you
> think the behaviour should be? If allow_unload_modules /
> allow_unregister_module is set, do you want to be able to call
> security_delete_hooks? What do you think the right
> action should be if it fails?

The one that avoids breakage for existing users ;)

I personally am in favor of killing SELinux support for runtime disable aka
CONFIG_SECURITY_SELINUX_DISABLE; the only reason it exists is that Red Hat
originally insisted that bootloader configuration is too painful to 
modify/update on
certain platforms and therefore the selinux=0 boot parameter is insufficient
as a mechanism for disabling SELinux.

However, we can't break existing users.  Userspace should still attempt to 
proceed
even if runtime disable fails, just with SELinux left in permissive mode and no
policy loaded.  That generally should work, but does retain the performance 
overhead
of the SELinux hook function processing, unlike a real disable.

I don't think we particularly care about allow_unload_modules / 
allow_unregister_module
since there is no existing userspace or configurations relying on it.





Re: [PATCH v5 1/1] security: Add mechanism to safely (un)load LSMs after boot time

2018-04-11 Thread Stephen Smalley
On 04/10/2018 05:24 PM, Sargun Dhillon wrote:
> On Sun, Apr 8, 2018 at 10:25 PM, Tetsuo Handa
>  wrote:
>> Sargun Dhillon wrote:
   Remove SECURITY_HOOK_COUNT and "struct security_hook_list"->owner and
   the exception in randomize_layout_plugin.c because preventing module
   unloading won't work as expected.

>>>
>>> Rather than completely removing the unloading code, might it make
>>> sense to add a BUG_ON or WARN_ON, in security_delete_hooks if
>>> allow_unload_module is false, and owner is not NULL?
>>
>> Do we need to check ->owner != NULL? Although it will be true that
>> SELinux's ->owner == NULL and LKM-based LSM module's ->owner != NULL,
>> I think we unregister SELinux before setting allow_unload_module to false.
>> Thus, rejecting delete_security_hooks() if allow_unload_module == false will
>> be sufficient. SELinux might want to call panic() if delete_security_hooks()
>> did not unregister due to allow_unload_module == false. Also,
>> allow_unload_module would be renamed to allow_unregister_module.
>>
>> By the way, please don't use BUG_ON() or WARN_ON() because syzbot would hit
>> and call panic() because syzbot runs tests with panic_on_warn == true.
> 
> I think my primary question is for the SELinux folks -- what do you
> think the behaviour should be? If allow_unload_modules /
> allow_unregister_module is set, do you want to be able to call
> security_delete_hooks? What do you think the right
> action should be if it fails?

The one that avoids breakage for existing users ;)

I personally am in favor of killing SELinux support for runtime disable aka
CONFIG_SECURITY_SELINUX_DISABLE; the only reason it exists is that Red Hat
originally insisted that bootloader configuration is too painful to 
modify/update on
certain platforms and therefore the selinux=0 boot parameter is insufficient
as a mechanism for disabling SELinux.

However, we can't break existing users.  Userspace should still attempt to 
proceed
even if runtime disable fails, just with SELinux left in permissive mode and no
policy loaded.  That generally should work, but does retain the performance 
overhead
of the SELinux hook function processing, unlike a real disable.

I don't think we particularly care about allow_unload_modules / 
allow_unregister_module
since there is no existing userspace or configurations relying on it.





Re: [PATCH v5 1/1] security: Add mechanism to safely (un)load LSMs after boot time

2018-04-10 Thread Sargun Dhillon
On Sun, Apr 8, 2018 at 10:25 PM, Tetsuo Handa
 wrote:
> Sargun Dhillon wrote:
>> >   Remove SECURITY_HOOK_COUNT and "struct security_hook_list"->owner and
>> >   the exception in randomize_layout_plugin.c because preventing module
>> >   unloading won't work as expected.
>> >
>>
>> Rather than completely removing the unloading code, might it make
>> sense to add a BUG_ON or WARN_ON, in security_delete_hooks if
>> allow_unload_module is false, and owner is not NULL?
>
> Do we need to check ->owner != NULL? Although it will be true that
> SELinux's ->owner == NULL and LKM-based LSM module's ->owner != NULL,
> I think we unregister SELinux before setting allow_unload_module to false.
> Thus, rejecting delete_security_hooks() if allow_unload_module == false will
> be sufficient. SELinux might want to call panic() if delete_security_hooks()
> did not unregister due to allow_unload_module == false. Also,
> allow_unload_module would be renamed to allow_unregister_module.
>
> By the way, please don't use BUG_ON() or WARN_ON() because syzbot would hit
> and call panic() because syzbot runs tests with panic_on_warn == true.

I think my primary question is for the SELinux folks -- what do you
think the behaviour should be? If allow_unload_modules /
allow_unregister_module is set, do you want to be able to call
security_delete_hooks? What do you think the right
action should be if it fails?


Re: [PATCH v5 1/1] security: Add mechanism to safely (un)load LSMs after boot time

2018-04-10 Thread Sargun Dhillon
On Sun, Apr 8, 2018 at 10:25 PM, Tetsuo Handa
 wrote:
> Sargun Dhillon wrote:
>> >   Remove SECURITY_HOOK_COUNT and "struct security_hook_list"->owner and
>> >   the exception in randomize_layout_plugin.c because preventing module
>> >   unloading won't work as expected.
>> >
>>
>> Rather than completely removing the unloading code, might it make
>> sense to add a BUG_ON or WARN_ON, in security_delete_hooks if
>> allow_unload_module is false, and owner is not NULL?
>
> Do we need to check ->owner != NULL? Although it will be true that
> SELinux's ->owner == NULL and LKM-based LSM module's ->owner != NULL,
> I think we unregister SELinux before setting allow_unload_module to false.
> Thus, rejecting delete_security_hooks() if allow_unload_module == false will
> be sufficient. SELinux might want to call panic() if delete_security_hooks()
> did not unregister due to allow_unload_module == false. Also,
> allow_unload_module would be renamed to allow_unregister_module.
>
> By the way, please don't use BUG_ON() or WARN_ON() because syzbot would hit
> and call panic() because syzbot runs tests with panic_on_warn == true.

I think my primary question is for the SELinux folks -- what do you
think the behaviour should be? If allow_unload_modules /
allow_unregister_module is set, do you want to be able to call
security_delete_hooks? What do you think the right
action should be if it fails?


Re: [PATCH v5 1/1] security: Add mechanism to safely (un)load LSMs after boot time

2018-04-08 Thread Tetsuo Handa
Sargun Dhillon wrote:
> >   Remove SECURITY_HOOK_COUNT and "struct security_hook_list"->owner and
> >   the exception in randomize_layout_plugin.c because preventing module
> >   unloading won't work as expected.
> >
> 
> Rather than completely removing the unloading code, might it make
> sense to add a BUG_ON or WARN_ON, in security_delete_hooks if
> allow_unload_module is false, and owner is not NULL?

Do we need to check ->owner != NULL? Although it will be true that
SELinux's ->owner == NULL and LKM-based LSM module's ->owner != NULL,
I think we unregister SELinux before setting allow_unload_module to false.
Thus, rejecting delete_security_hooks() if allow_unload_module == false will
be sufficient. SELinux might want to call panic() if delete_security_hooks()
did not unregister due to allow_unload_module == false. Also,
allow_unload_module would be renamed to allow_unregister_module.

By the way, please don't use BUG_ON() or WARN_ON() because syzbot would hit
and call panic() because syzbot runs tests with panic_on_warn == true.


Re: [PATCH v5 1/1] security: Add mechanism to safely (un)load LSMs after boot time

2018-04-08 Thread Tetsuo Handa
Sargun Dhillon wrote:
> >   Remove SECURITY_HOOK_COUNT and "struct security_hook_list"->owner and
> >   the exception in randomize_layout_plugin.c because preventing module
> >   unloading won't work as expected.
> >
> 
> Rather than completely removing the unloading code, might it make
> sense to add a BUG_ON or WARN_ON, in security_delete_hooks if
> allow_unload_module is false, and owner is not NULL?

Do we need to check ->owner != NULL? Although it will be true that
SELinux's ->owner == NULL and LKM-based LSM module's ->owner != NULL,
I think we unregister SELinux before setting allow_unload_module to false.
Thus, rejecting delete_security_hooks() if allow_unload_module == false will
be sufficient. SELinux might want to call panic() if delete_security_hooks()
did not unregister due to allow_unload_module == false. Also,
allow_unload_module would be renamed to allow_unregister_module.

By the way, please don't use BUG_ON() or WARN_ON() because syzbot would hit
and call panic() because syzbot runs tests with panic_on_warn == true.


Re: [PATCH v5 1/1] security: Add mechanism to safely (un)load LSMs after boot time

2018-04-08 Thread Sargun Dhillon
On Sun, Apr 8, 2018 at 8:38 PM, Tetsuo Handa
 wrote:
> Suggested changes on top of your patch:
>
>   Replace "struct hlist_head *head" in "struct security_hook_list" with
>   "const unsigned int offset" because there is no need to initialize with
>   address of the immutable/mutable chains.
>
>   Remove LSM_HOOK_INIT_MUTABLE() by embedding just offset (in bytes) from
>   head of "struct security_hook_heads" into "struct 
> security_hook_list"->offset.
>
>   Make "struct security_hook_heads security_hook_heads" and
>   "struct security_hook_heads security_hook_heads_mutable" local variables.
>
>   Rename "struct security_hook_heads security_hook_heads" to
>   "struct security_hook_heads security_mutable_hook_heads" and mark it as
>   __ro_after_init.
>
>   Add the fourth argument to security_add_hooks() which specifies to which
>   chain (security_{mutable|immutable}_hook_heads) to connect.
>
>   Make all built-in LSM modules (except SELinux if
>   CONFIG_SECURITY_SELINUX_DISABLE=y) be connected to
>   security_immutable_hook_heads.
>
>   Rename __lsm_ro_after_init to __selinux_ro_after_init which is local to
>   SELinux.
>
>   Mark "struct security_hook_list"->hook const because it won't change.
>
>   Mark "struct security_hook_list"->lsm const because none of
>   security_add_hooks() callers are ready to modify the third argument.
>
>   Remove SECURITY_HOOK_COUNT and "struct security_hook_list"->owner and
>   the exception in randomize_layout_plugin.c because preventing module
>   unloading won't work as expected.
>

Rather than completely removing the unloading code, might it make
sense to add a BUG_ON or WARN_ON, in security_delete_hooks if
allow_unload_module is false, and owner is not NULL?


Re: [PATCH v5 1/1] security: Add mechanism to safely (un)load LSMs after boot time

2018-04-08 Thread Sargun Dhillon
On Sun, Apr 8, 2018 at 8:38 PM, Tetsuo Handa
 wrote:
> Suggested changes on top of your patch:
>
>   Replace "struct hlist_head *head" in "struct security_hook_list" with
>   "const unsigned int offset" because there is no need to initialize with
>   address of the immutable/mutable chains.
>
>   Remove LSM_HOOK_INIT_MUTABLE() by embedding just offset (in bytes) from
>   head of "struct security_hook_heads" into "struct 
> security_hook_list"->offset.
>
>   Make "struct security_hook_heads security_hook_heads" and
>   "struct security_hook_heads security_hook_heads_mutable" local variables.
>
>   Rename "struct security_hook_heads security_hook_heads" to
>   "struct security_hook_heads security_mutable_hook_heads" and mark it as
>   __ro_after_init.
>
>   Add the fourth argument to security_add_hooks() which specifies to which
>   chain (security_{mutable|immutable}_hook_heads) to connect.
>
>   Make all built-in LSM modules (except SELinux if
>   CONFIG_SECURITY_SELINUX_DISABLE=y) be connected to
>   security_immutable_hook_heads.
>
>   Rename __lsm_ro_after_init to __selinux_ro_after_init which is local to
>   SELinux.
>
>   Mark "struct security_hook_list"->hook const because it won't change.
>
>   Mark "struct security_hook_list"->lsm const because none of
>   security_add_hooks() callers are ready to modify the third argument.
>
>   Remove SECURITY_HOOK_COUNT and "struct security_hook_list"->owner and
>   the exception in randomize_layout_plugin.c because preventing module
>   unloading won't work as expected.
>

Rather than completely removing the unloading code, might it make
sense to add a BUG_ON or WARN_ON, in security_delete_hooks if
allow_unload_module is false, and owner is not NULL?


Re: [PATCH v5 1/1] security: Add mechanism to safely (un)load LSMs after boot time

2018-04-08 Thread Tetsuo Handa
Suggested changes on top of your patch:

  Replace "struct hlist_head *head" in "struct security_hook_list" with
  "const unsigned int offset" because there is no need to initialize with
  address of the immutable/mutable chains.

  Remove LSM_HOOK_INIT_MUTABLE() by embedding just offset (in bytes) from
  head of "struct security_hook_heads" into "struct security_hook_list"->offset.

  Make "struct security_hook_heads security_hook_heads" and
  "struct security_hook_heads security_hook_heads_mutable" local variables.

  Rename "struct security_hook_heads security_hook_heads" to
  "struct security_hook_heads security_mutable_hook_heads" and mark it as
  __ro_after_init.

  Add the fourth argument to security_add_hooks() which specifies to which
  chain (security_{mutable|immutable}_hook_heads) to connect.

  Make all built-in LSM modules (except SELinux if
  CONFIG_SECURITY_SELINUX_DISABLE=y) be connected to
  security_immutable_hook_heads.

  Rename __lsm_ro_after_init to __selinux_ro_after_init which is local to
  SELinux.

  Mark "struct security_hook_list"->hook const because it won't change.

  Mark "struct security_hook_list"->lsm const because none of
  security_add_hooks() callers are ready to modify the third argument.

  Remove SECURITY_HOOK_COUNT and "struct security_hook_list"->owner and
  the exception in randomize_layout_plugin.c because preventing module
  unloading won't work as expected.

---
 include/linux/lsm_hooks.h |  23 +-
 scripts/gcc-plugins/randomize_layout_plugin.c |   2 -
 security/apparmor/lsm.c   |   4 +-
 security/commoncap.c  |   4 +-
 security/loadpin/loadpin.c|   5 +-
 security/security.c   |  52 +--
 security/selinux/hooks.c  | 437 +-
 security/smack/smack_lsm.c|   5 +-
 security/tomoyo/tomoyo.c  |   5 +-
 security/yama/yama_lsm.c  |   4 +-
 10 files changed, 265 insertions(+), 276 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 9cd7527..13d9d3a 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2006,11 +2006,10 @@ struct security_hook_heads {
  * For use with generic list macros for common operations.
  */
 struct security_hook_list {
-   struct hlist_node   list;
-   struct hlist_head   *head;
-   union security_list_options hook;
-   char*lsm;
-   struct module   *owner;
+   struct hlist_node   list;
+   const unsigned int  offset;
+   const union security_list_options   hook;
+   const char  *lsm;
 } __randomize_layout;
 
 /*
@@ -2021,26 +2020,16 @@ struct security_hook_list {
  */
 #define LSM_HOOK_INIT(HEAD, HOOK) \
{   \
-   .head = _hook_heads.HEAD,  \
+   .offset = offsetof(struct security_hook_heads, HEAD), \
.hook = { .HEAD = HOOK },   \
-   .owner = THIS_MODULE,   \
}
-extern struct security_hook_heads security_hook_heads;
 extern char *lsm_names;
 
 extern void security_add_hooks(struct security_hook_list *hooks, int count,
-   char *lsm);
+  const char *lsm, const bool dynamic);
 
-#define __lsm_ro_after_init__ro_after_init
 /* Used to facilitate runtime hook unloading, and loading */
 #ifdef CONFIG_SECURITY_WRITABLE_HOOKS
-#define LSM_HOOK_INIT_MUTABLE(HEAD, HOOK) \
-   {   \
-   .head = _hook_heads_mutable.HEAD,  \
-   .hook = { .HEAD = HOOK },   \
-   .owner = THIS_MODULE,   \
-   }
-extern struct security_hook_heads security_hook_heads_mutable;
 /*
  * Assuring the safety of deleting a security module is up to
  * the security module involved. This may entail ordering the
diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c 
b/scripts/gcc-plugins/randomize_layout_plugin.c
index 6d5bbd3..d941389 100644
--- a/scripts/gcc-plugins/randomize_layout_plugin.c
+++ b/scripts/gcc-plugins/randomize_layout_plugin.c
@@ -52,8 +52,6 @@ struct whitelist_entry {
{ "net/unix/af_unix.c", "unix_skb_parms", "char" },
/* big_key payload.data struct splashing */
{ "security/keys/big_key.c", "path", "void *" },
-   /* walk struct security_hook_heads as an array of struct hlist_head */
-   { "security/security.c", "hlist_head", "security_hook_heads" },
{ }
 };
 
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index cf00c85..0eb4e1b 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1118,7 +1118,7 @@ static void 

Re: [PATCH v5 1/1] security: Add mechanism to safely (un)load LSMs after boot time

2018-04-08 Thread Tetsuo Handa
Suggested changes on top of your patch:

  Replace "struct hlist_head *head" in "struct security_hook_list" with
  "const unsigned int offset" because there is no need to initialize with
  address of the immutable/mutable chains.

  Remove LSM_HOOK_INIT_MUTABLE() by embedding just offset (in bytes) from
  head of "struct security_hook_heads" into "struct security_hook_list"->offset.

  Make "struct security_hook_heads security_hook_heads" and
  "struct security_hook_heads security_hook_heads_mutable" local variables.

  Rename "struct security_hook_heads security_hook_heads" to
  "struct security_hook_heads security_mutable_hook_heads" and mark it as
  __ro_after_init.

  Add the fourth argument to security_add_hooks() which specifies to which
  chain (security_{mutable|immutable}_hook_heads) to connect.

  Make all built-in LSM modules (except SELinux if
  CONFIG_SECURITY_SELINUX_DISABLE=y) be connected to
  security_immutable_hook_heads.

  Rename __lsm_ro_after_init to __selinux_ro_after_init which is local to
  SELinux.

  Mark "struct security_hook_list"->hook const because it won't change.

  Mark "struct security_hook_list"->lsm const because none of
  security_add_hooks() callers are ready to modify the third argument.

  Remove SECURITY_HOOK_COUNT and "struct security_hook_list"->owner and
  the exception in randomize_layout_plugin.c because preventing module
  unloading won't work as expected.

---
 include/linux/lsm_hooks.h |  23 +-
 scripts/gcc-plugins/randomize_layout_plugin.c |   2 -
 security/apparmor/lsm.c   |   4 +-
 security/commoncap.c  |   4 +-
 security/loadpin/loadpin.c|   5 +-
 security/security.c   |  52 +--
 security/selinux/hooks.c  | 437 +-
 security/smack/smack_lsm.c|   5 +-
 security/tomoyo/tomoyo.c  |   5 +-
 security/yama/yama_lsm.c  |   4 +-
 10 files changed, 265 insertions(+), 276 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 9cd7527..13d9d3a 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2006,11 +2006,10 @@ struct security_hook_heads {
  * For use with generic list macros for common operations.
  */
 struct security_hook_list {
-   struct hlist_node   list;
-   struct hlist_head   *head;
-   union security_list_options hook;
-   char*lsm;
-   struct module   *owner;
+   struct hlist_node   list;
+   const unsigned int  offset;
+   const union security_list_options   hook;
+   const char  *lsm;
 } __randomize_layout;
 
 /*
@@ -2021,26 +2020,16 @@ struct security_hook_list {
  */
 #define LSM_HOOK_INIT(HEAD, HOOK) \
{   \
-   .head = _hook_heads.HEAD,  \
+   .offset = offsetof(struct security_hook_heads, HEAD), \
.hook = { .HEAD = HOOK },   \
-   .owner = THIS_MODULE,   \
}
-extern struct security_hook_heads security_hook_heads;
 extern char *lsm_names;
 
 extern void security_add_hooks(struct security_hook_list *hooks, int count,
-   char *lsm);
+  const char *lsm, const bool dynamic);
 
-#define __lsm_ro_after_init__ro_after_init
 /* Used to facilitate runtime hook unloading, and loading */
 #ifdef CONFIG_SECURITY_WRITABLE_HOOKS
-#define LSM_HOOK_INIT_MUTABLE(HEAD, HOOK) \
-   {   \
-   .head = _hook_heads_mutable.HEAD,  \
-   .hook = { .HEAD = HOOK },   \
-   .owner = THIS_MODULE,   \
-   }
-extern struct security_hook_heads security_hook_heads_mutable;
 /*
  * Assuring the safety of deleting a security module is up to
  * the security module involved. This may entail ordering the
diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c 
b/scripts/gcc-plugins/randomize_layout_plugin.c
index 6d5bbd3..d941389 100644
--- a/scripts/gcc-plugins/randomize_layout_plugin.c
+++ b/scripts/gcc-plugins/randomize_layout_plugin.c
@@ -52,8 +52,6 @@ struct whitelist_entry {
{ "net/unix/af_unix.c", "unix_skb_parms", "char" },
/* big_key payload.data struct splashing */
{ "security/keys/big_key.c", "path", "void *" },
-   /* walk struct security_hook_heads as an array of struct hlist_head */
-   { "security/security.c", "hlist_head", "security_hook_heads" },
{ }
 };
 
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index cf00c85..0eb4e1b 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1118,7 +1118,7 @@ static void