All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Cc: linux-security-module <linux-security-module@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	"kernel-hardening@lists.openwall.com" 
	<kernel-hardening@lists.openwall.com>,
	Casey Schaufler <casey@schaufler-ca.com>,
	Christoph Hellwig <hch@infradead.org>,
	Igor Stoppa <igor.stoppa@huawei.com>,
	James Morris <james.l.morris@oracle.com>,
	Paul Moore <paul@paul-moore.com>,
	Stephen Smalley <sds@tycho.nsa.gov>
Subject: Re: [PATCH] LSM: Convert security_hook_heads into explicit array of struct list_head
Date: Sat, 27 May 2017 18:04:14 -0700	[thread overview]
Message-ID: <CAGXu5jJ045iaDfoW+2dXU+U-KhfnNH1WX5ngUW9dHyS5Yn3EGg@mail.gmail.com> (raw)
In-Reply-To: <1495883858-3336-1-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp>

On Sat, May 27, 2017 at 4:17 AM, Tetsuo Handa
<penguin-kernel@i-love.sakura.ne.jp> wrote:
> Commit 3dfc9b02864b19f4 ("LSM: Initialize security_hook_heads upon
> registration.") treats "struct security_hook_heads" as an implicit array
> of "struct list_head" so that we can eliminate code for static
> initialization. Although we haven't encountered compilers which do not
> treat sizeof(security_hook_heads) != sizeof(struct list_head) *
> (sizeof(security_hook_heads) / sizeof(struct list_head)), Casey does not
> like the assumption that a structure of N elements can be assumed to be
> the same as an array of N elements.
>
> Now that Kees found that randstruct complains such casting
>
>   security/security.c: In function 'security_init':
>   security/security.c:59:20: note: found mismatched op0 struct pointer types: 'struct list_head' and 'struct security_hook_heads'
>
>     struct list_head *list = (struct list_head *) &security_hook_heads;
>
> and Christoph thinks that we should fix it rather than make randstruct
> whitelist it, this patch fixes it.
>
> It would be possible to revert commit 3dfc9b02864b19f4, but this patch
> converts security_hook_heads into an explicit array of struct list_head
> by introducing an enum, due to reasons explained below.

Like Casey, I had confused this patch with the other(?) that resulted
in dropped type checking. This just switches from named list_heads to
indexed list_heads, which is fine now that the BUG_ON exists to
sanity-check the index being used.

> In MM subsystem, a sealable memory allocator patch was proposed, and
> the LSM hooks ("struct security_hook_heads security_hook_heads" and
> "struct security_hook_list ...[]") will benefit from this allocator via
> protection using set_memory_ro()/set_memory_rw(), and that allocator
> will remove CONFIG_SECURITY_WRITABLE_HOOKS config option. Thus, we will
> likely be moving to that direction.

It's unlikely that smalloc will allow unsealing after initialization,
so the SELinux disabling case will remain, IIUC.

> This means that these structures will be allocated at run time using
> this allocator, and therefore the address of these structures will be
> determined at run time rather than compile time.
>
> But currently, LSM_HOOK_INIT() macro depends on the address of
> security_hook_heads being known at compile time. If we use an enum
> so that LSM_HOOK_INIT() macro does not need to know absolute address of
> security_hook_heads, it will help us to use that allocator for LSM hooks.
>
> As a result of introducing an enum, security_hook_heads becomes a local
> variable, making it easier to allocate security_hook_heads at run time.
>
> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Paul Moore <paul@paul-moore.com>
> Cc: Stephen Smalley <sds@tycho.nsa.gov>
> Cc: Casey Schaufler <casey@schaufler-ca.com>
> Cc: James Morris <james.l.morris@oracle.com>
> Cc: Igor Stoppa <igor.stoppa@huawei.com>
> Cc: Christoph Hellwig <hch@infradead.org>
> ---
>  include/linux/lsm_hooks.h | 412 +++++++++++++++++++++++-----------------------
>  security/security.c       |  38 +++--
>  2 files changed, 229 insertions(+), 221 deletions(-)
>
> diff --git a/security/security.c b/security/security.c
> index 38316bb..bd3c07e 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -179,7 +182,8 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
>         do {                                                    \
>                 struct security_hook_list *P;                   \
>                                                                 \
> -               list_for_each_entry(P, &security_hook_heads.FUNC, list) \
> +               list_for_each_entry(P, &security_hook_heads     \
> +                                   [LSM_##FUNC], list)         \

Can this be unsplit so the [...] remains next to security_hook_heads?

>                         P->hook.FUNC(__VA_ARGS__);              \
>         } while (0)
>
> @@ -188,7 +192,8 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
>         do {                                                    \
>                 struct security_hook_list *P;                   \
>                                                                 \
> -               list_for_each_entry(P, &security_hook_heads.FUNC, list) { \
> +               list_for_each_entry(P, &security_hook_heads     \
> +                                   [LSM_##FUNC], list) {       \

Same

>                         RC = P->hook.FUNC(__VA_ARGS__);         \
>                         if (RC != 0)                            \
>                                 break;                          \
> @@ -1587,8 +1595,8 @@ int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
>          * For speed optimization, we explicitly break the loop rather than
>          * using the macro
>          */
> -       list_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match,
> -                               list) {
> +       list_for_each_entry(hp, &security_hook_heads
> +                           [LSM_xfrm_state_pol_flow_match], list) {

Same

>                 rc = hp->hook.xfrm_state_pol_flow_match(x, xp, fl);
>                 break;
>         }
> --
> 1.8.3.1
>

Otherwise, yeah, I can be convinced to take this. :) Thanks for
persisting with this, I think it makes sense now.

-Kees

-- 
Kees Cook
Pixel Security

WARNING: multiple messages have this Message-ID (diff)
From: keescook@chromium.org (Kees Cook)
To: linux-security-module@vger.kernel.org
Subject: [PATCH] LSM: Convert security_hook_heads into explicit array of struct list_head
Date: Sat, 27 May 2017 18:04:14 -0700	[thread overview]
Message-ID: <CAGXu5jJ045iaDfoW+2dXU+U-KhfnNH1WX5ngUW9dHyS5Yn3EGg@mail.gmail.com> (raw)
In-Reply-To: <1495883858-3336-1-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp>

On Sat, May 27, 2017 at 4:17 AM, Tetsuo Handa
<penguin-kernel@i-love.sakura.ne.jp> wrote:
> Commit 3dfc9b02864b19f4 ("LSM: Initialize security_hook_heads upon
> registration.") treats "struct security_hook_heads" as an implicit array
> of "struct list_head" so that we can eliminate code for static
> initialization. Although we haven't encountered compilers which do not
> treat sizeof(security_hook_heads) != sizeof(struct list_head) *
> (sizeof(security_hook_heads) / sizeof(struct list_head)), Casey does not
> like the assumption that a structure of N elements can be assumed to be
> the same as an array of N elements.
>
> Now that Kees found that randstruct complains such casting
>
>   security/security.c: In function 'security_init':
>   security/security.c:59:20: note: found mismatched op0 struct pointer types: 'struct list_head' and 'struct security_hook_heads'
>
>     struct list_head *list = (struct list_head *) &security_hook_heads;
>
> and Christoph thinks that we should fix it rather than make randstruct
> whitelist it, this patch fixes it.
>
> It would be possible to revert commit 3dfc9b02864b19f4, but this patch
> converts security_hook_heads into an explicit array of struct list_head
> by introducing an enum, due to reasons explained below.

Like Casey, I had confused this patch with the other(?) that resulted
in dropped type checking. This just switches from named list_heads to
indexed list_heads, which is fine now that the BUG_ON exists to
sanity-check the index being used.

> In MM subsystem, a sealable memory allocator patch was proposed, and
> the LSM hooks ("struct security_hook_heads security_hook_heads" and
> "struct security_hook_list ...[]") will benefit from this allocator via
> protection using set_memory_ro()/set_memory_rw(), and that allocator
> will remove CONFIG_SECURITY_WRITABLE_HOOKS config option. Thus, we will
> likely be moving to that direction.

It's unlikely that smalloc will allow unsealing after initialization,
so the SELinux disabling case will remain, IIUC.

> This means that these structures will be allocated at run time using
> this allocator, and therefore the address of these structures will be
> determined at run time rather than compile time.
>
> But currently, LSM_HOOK_INIT() macro depends on the address of
> security_hook_heads being known at compile time. If we use an enum
> so that LSM_HOOK_INIT() macro does not need to know absolute address of
> security_hook_heads, it will help us to use that allocator for LSM hooks.
>
> As a result of introducing an enum, security_hook_heads becomes a local
> variable, making it easier to allocate security_hook_heads at run time.
>
> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Paul Moore <paul@paul-moore.com>
> Cc: Stephen Smalley <sds@tycho.nsa.gov>
> Cc: Casey Schaufler <casey@schaufler-ca.com>
> Cc: James Morris <james.l.morris@oracle.com>
> Cc: Igor Stoppa <igor.stoppa@huawei.com>
> Cc: Christoph Hellwig <hch@infradead.org>
> ---
>  include/linux/lsm_hooks.h | 412 +++++++++++++++++++++++-----------------------
>  security/security.c       |  38 +++--
>  2 files changed, 229 insertions(+), 221 deletions(-)
>
> diff --git a/security/security.c b/security/security.c
> index 38316bb..bd3c07e 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -179,7 +182,8 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
>         do {                                                    \
>                 struct security_hook_list *P;                   \
>                                                                 \
> -               list_for_each_entry(P, &security_hook_heads.FUNC, list) \
> +               list_for_each_entry(P, &security_hook_heads     \
> +                                   [LSM_##FUNC], list)         \

Can this be unsplit so the [...] remains next to security_hook_heads?

>                         P->hook.FUNC(__VA_ARGS__);              \
>         } while (0)
>
> @@ -188,7 +192,8 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
>         do {                                                    \
>                 struct security_hook_list *P;                   \
>                                                                 \
> -               list_for_each_entry(P, &security_hook_heads.FUNC, list) { \
> +               list_for_each_entry(P, &security_hook_heads     \
> +                                   [LSM_##FUNC], list) {       \

Same

>                         RC = P->hook.FUNC(__VA_ARGS__);         \
>                         if (RC != 0)                            \
>                                 break;                          \
> @@ -1587,8 +1595,8 @@ int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
>          * For speed optimization, we explicitly break the loop rather than
>          * using the macro
>          */
> -       list_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match,
> -                               list) {
> +       list_for_each_entry(hp, &security_hook_heads
> +                           [LSM_xfrm_state_pol_flow_match], list) {

Same

>                 rc = hp->hook.xfrm_state_pol_flow_match(x, xp, fl);
>                 break;
>         }
> --
> 1.8.3.1
>

Otherwise, yeah, I can be convinced to take this. :) Thanks for
persisting with this, I think it makes sense now.

-Kees

-- 
Kees Cook
Pixel Security
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

WARNING: multiple messages have this Message-ID (diff)
From: Kees Cook <keescook@chromium.org>
To: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Cc: linux-security-module <linux-security-module@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	"kernel-hardening@lists.openwall.com"
	<kernel-hardening@lists.openwall.com>,
	Casey Schaufler <casey@schaufler-ca.com>,
	Christoph Hellwig <hch@infradead.org>,
	Igor Stoppa <igor.stoppa@huawei.com>,
	James Morris <james.l.morris@oracle.com>,
	Paul Moore <paul@paul-moore.com>,
	Stephen Smalley <sds@tycho.nsa.gov>
Subject: [kernel-hardening] Re: [PATCH] LSM: Convert security_hook_heads into explicit array of struct list_head
Date: Sat, 27 May 2017 18:04:14 -0700	[thread overview]
Message-ID: <CAGXu5jJ045iaDfoW+2dXU+U-KhfnNH1WX5ngUW9dHyS5Yn3EGg@mail.gmail.com> (raw)
In-Reply-To: <1495883858-3336-1-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp>

On Sat, May 27, 2017 at 4:17 AM, Tetsuo Handa
<penguin-kernel@i-love.sakura.ne.jp> wrote:
> Commit 3dfc9b02864b19f4 ("LSM: Initialize security_hook_heads upon
> registration.") treats "struct security_hook_heads" as an implicit array
> of "struct list_head" so that we can eliminate code for static
> initialization. Although we haven't encountered compilers which do not
> treat sizeof(security_hook_heads) != sizeof(struct list_head) *
> (sizeof(security_hook_heads) / sizeof(struct list_head)), Casey does not
> like the assumption that a structure of N elements can be assumed to be
> the same as an array of N elements.
>
> Now that Kees found that randstruct complains such casting
>
>   security/security.c: In function 'security_init':
>   security/security.c:59:20: note: found mismatched op0 struct pointer types: 'struct list_head' and 'struct security_hook_heads'
>
>     struct list_head *list = (struct list_head *) &security_hook_heads;
>
> and Christoph thinks that we should fix it rather than make randstruct
> whitelist it, this patch fixes it.
>
> It would be possible to revert commit 3dfc9b02864b19f4, but this patch
> converts security_hook_heads into an explicit array of struct list_head
> by introducing an enum, due to reasons explained below.

Like Casey, I had confused this patch with the other(?) that resulted
in dropped type checking. This just switches from named list_heads to
indexed list_heads, which is fine now that the BUG_ON exists to
sanity-check the index being used.

> In MM subsystem, a sealable memory allocator patch was proposed, and
> the LSM hooks ("struct security_hook_heads security_hook_heads" and
> "struct security_hook_list ...[]") will benefit from this allocator via
> protection using set_memory_ro()/set_memory_rw(), and that allocator
> will remove CONFIG_SECURITY_WRITABLE_HOOKS config option. Thus, we will
> likely be moving to that direction.

It's unlikely that smalloc will allow unsealing after initialization,
so the SELinux disabling case will remain, IIUC.

> This means that these structures will be allocated at run time using
> this allocator, and therefore the address of these structures will be
> determined at run time rather than compile time.
>
> But currently, LSM_HOOK_INIT() macro depends on the address of
> security_hook_heads being known at compile time. If we use an enum
> so that LSM_HOOK_INIT() macro does not need to know absolute address of
> security_hook_heads, it will help us to use that allocator for LSM hooks.
>
> As a result of introducing an enum, security_hook_heads becomes a local
> variable, making it easier to allocate security_hook_heads at run time.
>
> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Paul Moore <paul@paul-moore.com>
> Cc: Stephen Smalley <sds@tycho.nsa.gov>
> Cc: Casey Schaufler <casey@schaufler-ca.com>
> Cc: James Morris <james.l.morris@oracle.com>
> Cc: Igor Stoppa <igor.stoppa@huawei.com>
> Cc: Christoph Hellwig <hch@infradead.org>
> ---
>  include/linux/lsm_hooks.h | 412 +++++++++++++++++++++++-----------------------
>  security/security.c       |  38 +++--
>  2 files changed, 229 insertions(+), 221 deletions(-)
>
> diff --git a/security/security.c b/security/security.c
> index 38316bb..bd3c07e 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -179,7 +182,8 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
>         do {                                                    \
>                 struct security_hook_list *P;                   \
>                                                                 \
> -               list_for_each_entry(P, &security_hook_heads.FUNC, list) \
> +               list_for_each_entry(P, &security_hook_heads     \
> +                                   [LSM_##FUNC], list)         \

Can this be unsplit so the [...] remains next to security_hook_heads?

>                         P->hook.FUNC(__VA_ARGS__);              \
>         } while (0)
>
> @@ -188,7 +192,8 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
>         do {                                                    \
>                 struct security_hook_list *P;                   \
>                                                                 \
> -               list_for_each_entry(P, &security_hook_heads.FUNC, list) { \
> +               list_for_each_entry(P, &security_hook_heads     \
> +                                   [LSM_##FUNC], list) {       \

Same

>                         RC = P->hook.FUNC(__VA_ARGS__);         \
>                         if (RC != 0)                            \
>                                 break;                          \
> @@ -1587,8 +1595,8 @@ int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
>          * For speed optimization, we explicitly break the loop rather than
>          * using the macro
>          */
> -       list_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match,
> -                               list) {
> +       list_for_each_entry(hp, &security_hook_heads
> +                           [LSM_xfrm_state_pol_flow_match], list) {

Same

>                 rc = hp->hook.xfrm_state_pol_flow_match(x, xp, fl);
>                 break;
>         }
> --
> 1.8.3.1
>

Otherwise, yeah, I can be convinced to take this. :) Thanks for
persisting with this, I think it makes sense now.

-Kees

-- 
Kees Cook
Pixel Security

  parent reply	other threads:[~2017-05-28  1:04 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-27 11:17 [PATCH] LSM: Convert security_hook_heads into explicit array of struct list_head Tetsuo Handa
2017-05-27 11:17 ` [kernel-hardening] " Tetsuo Handa
2017-05-27 11:17 ` Tetsuo Handa
2017-05-27 22:30 ` Casey Schaufler
2017-05-27 22:30   ` [kernel-hardening] " Casey Schaufler
2017-05-27 22:30   ` Casey Schaufler
2017-05-28  0:38   ` Tetsuo Handa
2017-05-28  0:38     ` [kernel-hardening] " Tetsuo Handa
2017-05-28  0:38     ` Tetsuo Handa
2017-05-28  1:04 ` Kees Cook [this message]
2017-05-28  1:04   ` [kernel-hardening] " Kees Cook
2017-05-28  1:04   ` Kees Cook
2017-05-28  1:26   ` Tetsuo Handa
2017-05-28  1:26     ` [kernel-hardening] " Tetsuo Handa
2017-05-28  1:26     ` Tetsuo Handa
2017-05-28 17:57     ` Casey Schaufler
2017-05-28 17:57       ` [kernel-hardening] " Casey Schaufler
2017-05-28 17:57       ` Casey Schaufler
2017-05-30 10:22     ` James Morris
2017-05-30 10:22       ` [kernel-hardening] " James Morris
2017-05-30 10:22       ` James Morris
2017-05-30 14:29       ` Tetsuo Handa
2017-05-30 14:29         ` [kernel-hardening] " Tetsuo Handa
2017-05-30 14:29         ` Tetsuo Handa
2017-05-30 15:25         ` Alan Cox
2017-05-30 15:25           ` [kernel-hardening] " Alan Cox
2017-05-30 15:25           ` Alan Cox
2017-05-30 23:06           ` James Morris
2017-05-30 23:06             ` [kernel-hardening] " James Morris
2017-05-30 23:06             ` James Morris
2017-05-31 10:41             ` Tetsuo Handa
2017-05-31 10:41               ` [kernel-hardening] " Tetsuo Handa
2017-05-31 10:41               ` Tetsuo Handa
2017-05-31 11:04               ` James Morris
2017-05-31 11:04                 ` [kernel-hardening] " James Morris
2017-05-31 11:04                 ` James Morris
2017-05-31 11:31                 ` Tetsuo Handa
2017-05-31 11:31                   ` [kernel-hardening] " Tetsuo Handa
2017-05-31 11:31                   ` Tetsuo Handa
2017-05-31 14:43               ` Alan Cox
2017-05-31 14:43                 ` [kernel-hardening] " Alan Cox
2017-05-31 14:43                 ` Alan Cox
2017-05-31 15:10                 ` Tetsuo Handa
2017-05-31 15:10                   ` [kernel-hardening] " Tetsuo Handa
2017-05-31 15:10                   ` Tetsuo Handa
2017-05-31 15:14                   ` Alan Cox
2017-05-31 15:14                     ` [kernel-hardening] " Alan Cox
2017-05-31 15:14                     ` Alan Cox
2017-05-31  9:44         ` José Bollo
2017-05-31  9:44           ` [kernel-hardening] " José Bollo
2017-05-31  9:44           ` José Bollo
2017-05-28 20:29 ` [PATCH v2] " Tetsuo Handa
2017-05-28 20:29   ` [kernel-hardening] " Tetsuo Handa
2017-05-28 20:29   ` Tetsuo Handa
2017-05-28 21:19   ` Kees Cook
2017-05-28 21:19     ` [kernel-hardening] " Kees Cook
2017-05-28 21:19     ` Kees Cook
2017-05-29 17:32   ` Casey Schaufler
2017-05-29 17:32     ` [kernel-hardening] " Casey Schaufler
2017-05-29 17:32     ` Casey Schaufler
2017-05-30 10:32   ` James Morris
2017-05-30 10:32     ` [kernel-hardening] " James Morris
2017-05-30 10:32     ` James Morris
2017-05-31 20:49     ` Igor Stoppa
2017-05-31 20:49       ` [kernel-hardening] " Igor Stoppa
2017-05-31 20:49       ` Igor Stoppa
2017-05-31 22:56       ` James Morris
2017-05-31 22:56         ` [kernel-hardening] " James Morris
2017-05-31 22:56         ` James Morris

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=CAGXu5jJ045iaDfoW+2dXU+U-KhfnNH1WX5ngUW9dHyS5Yn3EGg@mail.gmail.com \
    --to=keescook@chromium.org \
    --cc=casey@schaufler-ca.com \
    --cc=hch@infradead.org \
    --cc=igor.stoppa@huawei.com \
    --cc=james.l.morris@oracle.com \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=paul@paul-moore.com \
    --cc=penguin-kernel@i-love.sakura.ne.jp \
    --cc=sds@tycho.nsa.gov \
    /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.