2009-09-13 02:55:09

by Eric Paris

[permalink] [raw]
Subject: [PATCH 1/3] Creds: creds->security can be NULL is selinux is disabled

__validate_process_creds should check if selinux is actually enabled before
running tests on the selinux portion of the credentials struct.

Signed-off-by: Eric Paris <[email protected]>
---

include/linux/cred.h | 13 ++++++++-----
include/linux/selinux.h | 9 +++++++++
security/selinux/exports.c | 6 ++++++
3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/include/linux/cred.h b/include/linux/cred.h
index 24520a5..fb37160 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -15,6 +15,7 @@
#include <linux/capability.h>
#include <linux/init.h>
#include <linux/key.h>
+#include <linux/selinux.h>
#include <asm/atomic.h>

struct user_struct;
@@ -182,11 +183,13 @@ static inline bool creds_are_invalid(const struct cred *cred)
if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers))
return true;
#ifdef CONFIG_SECURITY_SELINUX
- if ((unsigned long) cred->security < PAGE_SIZE)
- return true;
- if ((*(u32*)cred->security & 0xffffff00) ==
- (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8))
- return true;
+ if (selinux_is_enabled()) {
+ if ((unsigned long) cred->security < PAGE_SIZE)
+ return true;
+ if ((*(u32 *)cred->security & 0xffffff00) ==
+ (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8))
+ return true;
+ }
#endif
return false;
}
diff --git a/include/linux/selinux.h b/include/linux/selinux.h
index 20f965d..223d06a 100644
--- a/include/linux/selinux.h
+++ b/include/linux/selinux.h
@@ -61,6 +61,11 @@ void selinux_secmark_refcount_inc(void);
* existing SECMARK targets has been removed/flushed.
*/
void selinux_secmark_refcount_dec(void);
+
+/**
+ * selinux_is_enabled - is SELinux enabled?
+ */
+bool selinux_is_enabled(void);
#else

static inline int selinux_string_to_sid(const char *str, u32 *sid)
@@ -84,6 +89,10 @@ static inline void selinux_secmark_refcount_dec(void)
return;
}

+static bool selinux_is_enabled(void)
+{
+ return false;
+}
#endif /* CONFIG_SECURITY_SELINUX */

#endif /* _LINUX_SELINUX_H */
diff --git a/security/selinux/exports.c b/security/selinux/exports.c
index c73aeaa..c0a454a 100644
--- a/security/selinux/exports.c
+++ b/security/selinux/exports.c
@@ -63,3 +63,9 @@ void selinux_secmark_refcount_dec(void)
atomic_dec(&selinux_secmark_refcount);
}
EXPORT_SYMBOL_GPL(selinux_secmark_refcount_dec);
+
+bool selinux_is_enabled(void)
+{
+ return selinux_enabled;
+}
+EXPORT_SYMBOL_GPL(selinux_is_enabled);


2009-09-13 02:55:16

by Eric Paris

[permalink] [raw]
Subject: [PATCH 2/3] SELinux: seperate avc_cache flushing

Move the avc_cache flushing into it's own function so it can be reused when
disabling SELinux.

Signed-off-by: Eric Paris <[email protected]>
---

security/selinux/avc.c | 24 +++++++++++++++++-------
1 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index e3d1901..f601246 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -709,18 +709,16 @@ out:
}

/**
- * avc_ss_reset - Flush the cache and revalidate migrated permissions.
- * @seqno: policy sequence number
+ * avc_flush - Flush the cache
*/
-int avc_ss_reset(u32 seqno)
+static void avc_flush(void)
{
- struct avc_callback_node *c;
- int i, rc = 0, tmprc;
- unsigned long flag;
- struct avc_node *node;
struct hlist_head *head;
struct hlist_node *next;
+ struct avc_node *node;
spinlock_t *lock;
+ unsigned long flag;
+ int i;

for (i = 0; i < AVC_CACHE_SLOTS; i++) {
head = &avc_cache.slots[i];
@@ -737,6 +735,18 @@ int avc_ss_reset(u32 seqno)
rcu_read_unlock();
spin_unlock_irqrestore(lock, flag);
}
+}
+
+/**
+ * avc_ss_reset - Flush the cache and revalidate migrated permissions.
+ * @seqno: policy sequence number
+ */
+int avc_ss_reset(u32 seqno)
+{
+ struct avc_callback_node *c;
+ int rc = 0, tmprc;
+
+ avc_flush();

for (c = avc_callbacks; c; c = c->next) {
if (c->events & AVC_CALLBACK_RESET) {

2009-09-13 02:55:34

by Eric Paris

[permalink] [raw]
Subject: [PATCH 3/3] SELinux: flush the avc before disabling SELinux

Before SELinux is disabled at boot it can create AVC entries. This patch
will flush those entries before disabling SELinux.

Signed-off-by: Eric Paris <[email protected]>
---

security/selinux/avc.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index f601246..1ed0f07 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -868,6 +868,8 @@ u32 avc_policy_seqno(void)

void avc_disable(void)
{
+ avc_flush();
+ synchronize_rcu();
if (avc_node_cachep)
kmem_cache_destroy(avc_node_cachep);
}

2009-09-13 22:24:15

by James Morris

[permalink] [raw]
Subject: Re: [PATCH 1/3] Creds: creds->security can be NULL is selinux is disabled

On Sat, 12 Sep 2009, Eric Paris wrote:

> __validate_process_creds should check if selinux is actually enabled before
> running tests on the selinux portion of the credentials struct.

Have you verified that this fixes the problem?


--
James Morris
<[email protected]>

2009-09-13 22:56:51

by Eric Paris

[permalink] [raw]
Subject: Re: [PATCH 1/3] Creds: creds->security can be NULL is selinux is disabled

On Mon, 2009-09-14 at 08:23 +1000, James Morris wrote:
> On Sat, 12 Sep 2009, Eric Paris wrote:
>
> > __validate_process_creds should check if selinux is actually enabled before
> > running tests on the selinux portion of the credentials struct.
>
> Have you verified that this fixes the problem?

Yes, I was able to reproduce the problem using selinux=0 at the command
line. This patch fixes the problem.

-Eric

2009-09-14 02:59:05

by James Morris

[permalink] [raw]
Subject: [GIT] fix creds / SELinux regressions

Hi Linus, please pull.


The following changes since commit 86d710146fb9975f04c505ec78caa43d227c1018:
Linus Torvalds (1):
Merge git://git.linux-nfs.org/projects/trondmy/nfs-2.6

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6 for-linus

Eric Paris (3):
Creds: creds->security can be NULL is selinux is disabled
SELinux: seperate avc_cache flushing
SELinux: flush the avc before disabling SELinux

include/linux/cred.h | 13 ++++++++-----
include/linux/selinux.h | 9 +++++++++
security/selinux/avc.c | 26 +++++++++++++++++++-------
security/selinux/exports.c | 6 ++++++
4 files changed, 42 insertions(+), 12 deletions(-)

--
James Morris
<[email protected]>

2009-09-14 04:21:50

by Ingo Molnar

[permalink] [raw]
Subject: Re: [GIT] fix creds / SELinux regressions


* James Morris <[email protected]> wrote:

> Hi Linus, please pull.
>
>
> The following changes since commit 86d710146fb9975f04c505ec78caa43d227c1018:
> Linus Torvalds (1):
> Merge git://git.linux-nfs.org/projects/trondmy/nfs-2.6
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6 for-linus
>
> Eric Paris (3):
> Creds: creds->security can be NULL is selinux is disabled
> SELinux: seperate avc_cache flushing
> SELinux: flush the avc before disabling SELinux
>
> include/linux/cred.h | 13 ++++++++-----
> include/linux/selinux.h | 9 +++++++++
> security/selinux/avc.c | 26 +++++++++++++++++++-------
> security/selinux/exports.c | 6 ++++++
> 4 files changed, 42 insertions(+), 12 deletions(-)

Guys, _please_ do better changelogs and describe how bugs were
found. It doesnt matter for me personally but these commit logs
utterly lack any description about how the bugs were
found/triggered, how relevant they are in practice, there's no
crashlog signatures in them for people to check, no Reported-by
lines, etc.

Ingo

2009-09-14 11:53:46

by David Howells

[permalink] [raw]
Subject: Re: [PATCH 1/3] Creds: creds->security can be NULL is selinux is disabled

Eric Paris <[email protected]> wrote:

> __validate_process_creds should check if selinux is actually enabled before
> running tests on the selinux portion of the credentials struct.
>
> Signed-off-by: Eric Paris <[email protected]>

Acked-by: David Howells <[email protected]>