All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] selinux: Only attempt to load policy exactly once, in the real root
@ 2014-02-20 15:42 Colin Walters
  2014-02-20 18:06 ` Stephen Smalley
  0 siblings, 1 reply; 15+ messages in thread
From: Colin Walters @ 2014-02-20 15:42 UTC (permalink / raw)
  To: SELinux-NSA; +Cc: systemd Mailing List


[-- Attachment #1.1: Type: text/plain, Size: 1325 bytes --]

Currently on at least Fedora, SELinux policy does not come in
the initramfs. systemd will attempt to load *both* in the
initramfs and in the real root.

Now, the selinux_init_load_policy() API has a regular error return
value, as well as an "enforcing" boolean. To determine enforcing
state, it looks for /etc/selinux/config as well as the presence
of "enforcing=" on the kernel command line.

Ordinarily, neither of those exist in the initramfs, so it will return
"unknown" for enforcing, and systemd will simply ignore the failure to
load policy.

Then later after we switch to the real root, we have the config file,
and all will work properly.

Except...this all blows up if someone explicitly specifies enforcing=1
on the kernel command line. Then systemd will fail to load the
nonexistent policy in the initramfs and freeze.

What this patch does is quite simple - we add an internal API that
says where we expect to find policy, and attempt to load it exactly
from there. Right now since I'm not aware of anyone who does
policy-in-initramfs, this function is hardcoded to return false.

Lots-of-very-painful-debugging-by: Colin Walters <walters@verbum.org>
---
 src/core/main.c | 6 ++++--
 src/core/selinux-setup.c | 10 ++++++++++
 src/core/selinux-setup.h | 2 ++
 3 files changed, 16 insertions(+), 2 deletions(-)




[-- Attachment #1.2: Type: text/html, Size: 1716 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-selinux-Only-attempt-to-load-policy-exactly-once-in-.patch --]
[-- Type: text/x-patch, Size: 3275 bytes --]

>From b109b6e0c1ea7509f08a09d66072c86bea279a06 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Thu, 20 Feb 2014 10:15:10 -0500
Subject: [PATCH] selinux: Only attempt to load policy exactly once, in the
 real root

Currently on at least Fedora, SELinux policy does not come in
the initramfs.  systemd will attempt to load *both* in the
initramfs and in the real root.

Now, the selinux_init_load_policy() API has a regular error return
value, as well as an "enforcing" boolean.  To determine enforcing
state, it looks for /etc/selinux/config as well as the presence
of "enforcing=" on the kernel command line.

Ordinarily, neither of those exist in the initramfs, so it will return
"unknown" for enforcing, and systemd will simply ignore the failure to
load policy.

Then later after we switch to the real root, we have the config file,
and all will work properly.

Except...this all blows up if someone explicitly specifies enforcing=1
on the kernel command line.  Then systemd will fail to load the
nonexistent policy in the initramfs and freeze.

What this patch does is quite simple - we add an internal API that
says where we expect to find policy, and attempt to load it exactly
from there.  Right now since I'm not aware of anyone who does
policy-in-initramfs, this function is hardcoded to return false.

Lots-of-very-painful-debugging-by: Colin Walters <walters@verbum.org>
---
 src/core/main.c          |  6 ++++--
 src/core/selinux-setup.c | 10 ++++++++++
 src/core/selinux-setup.h |  2 ++
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/core/main.c b/src/core/main.c
index 58c3a9e..8a13b54 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1296,8 +1296,10 @@ int main(int argc, char *argv[]) {
 
                 if (!skip_setup) {
                         mount_setup_early();
-                        if (selinux_setup(&loaded_policy) < 0)
-                                goto finish;
+                        if (in_initrd() == selinux_load_policy_in_initramfs()) {
+                                if (selinux_setup(&loaded_policy) < 0)
+                                        goto finish;
+                        }
                         if (ima_setup() < 0)
                                 goto finish;
                         if (smack_setup() < 0)
diff --git a/src/core/selinux-setup.c b/src/core/selinux-setup.c
index 7a32ed5..f689149 100644
--- a/src/core/selinux-setup.c
+++ b/src/core/selinux-setup.c
@@ -37,6 +37,16 @@
 #include "util.h"
 #include "log.h"
 
+/**
+ * At present, I'm not aware of a SELinux user who loads the policy
+ * from the initramfs.  If you are such a user, you can flip this
+ * define with a patch.  Alternatively in the future, this information
+ * could come from the kernel command line.
+ */
+bool selinux_load_policy_in_initramfs(void) {
+        return false;
+}
+
 #ifdef HAVE_SELINUX
 static int null_log(int type, const char *fmt, ...) {
         return 0;
diff --git a/src/core/selinux-setup.h b/src/core/selinux-setup.h
index 39e2bc2..d3f3bbc 100644
--- a/src/core/selinux-setup.h
+++ b/src/core/selinux-setup.h
@@ -23,4 +23,6 @@
 
 #include <stdbool.h>
 
+bool selinux_load_policy_in_initramfs(void);
+
 int selinux_setup(bool *loaded_policy);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 15:42 [PATCH] selinux: Only attempt to load policy exactly once, in the real root Colin Walters
@ 2014-02-20 18:06 ` Stephen Smalley
  2014-02-20 18:17   ` Colin Walters
  0 siblings, 1 reply; 15+ messages in thread
From: Stephen Smalley @ 2014-02-20 18:06 UTC (permalink / raw)
  To: Colin Walters, SELinux-NSA; +Cc: systemd Mailing List

On 02/20/2014 10:42 AM, Colin Walters wrote:
> Currently on at least Fedora, SELinux policy does not come in
> the initramfs. systemd will attempt to load *both* in the
> initramfs and in the real root.
> 
> Now, the selinux_init_load_policy() API has a regular error return
> value, as well as an "enforcing" boolean. To determine enforcing
> state, it looks for /etc/selinux/config as well as the presence
> of "enforcing=" on the kernel command line.
> 
> Ordinarily, neither of those exist in the initramfs, so it will return
> "unknown" for enforcing, and systemd will simply ignore the failure to
> load policy.
> 
> Then later after we switch to the real root, we have the config file,
> and all will work properly.
> 
> Except...this all blows up if someone explicitly specifies enforcing=1
> on the kernel command line. Then systemd will fail to load the
> nonexistent policy in the initramfs and freeze.
> 
> What this patch does is quite simple - we add an internal API that
> says where we expect to find policy, and attempt to load it exactly
> from there. Right now since I'm not aware of anyone who does
> policy-in-initramfs, this function is hardcoded to return false.
> 
> Lots-of-very-painful-debugging-by: Colin Walters <walters@verbum.org>
> ---
> src/core/main.c | 6 ++++--
> src/core/selinux-setup.c | 10 ++++++++++
> src/core/selinux-setup.h | 2 ++
> 3 files changed, 16 insertions(+), 2 deletions(-)

Wouldn't it be better (and more correct) to probe both the initramfs and
the real root, and if neither one can load policy successfully and
enforcing=1, then halt?

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 18:06 ` Stephen Smalley
@ 2014-02-20 18:17   ` Colin Walters
  2014-02-20 18:36     ` [systemd-devel] " Lennart Poettering
  2014-02-20 18:51     ` Stephen Smalley
  0 siblings, 2 replies; 15+ messages in thread
From: Colin Walters @ 2014-02-20 18:17 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: systemd Mailing List, SELinux-NSA

[-- Attachment #1: Type: text/plain, Size: 1010 bytes --]

On Thu, Feb 20, 2014 at 1:06 PM, Stephen Smalley <sds@tycho.nsa.gov> 
wrote:
> 
> Wouldn't it be better (and more correct) to probe both the initramfs 
> and
> the real root, and if neither one can load policy successfully and
> enforcing=1, then halt?
> 
So you're saying we should handle -ENOENT specially in the initramfs?  
Something like being sure we preserve errno and returning it to the 
caller of selinux_init_load_policy()?  That would introduce a subtle 
version dependency.

Or alternatively, just try in the initramfs, ignore any errors, and 
only abort if we also fail to load in the real root?

I think both of these (particularly the second) are worse than my patch 
- we don't (to my knowledge) support putting policy in the initramfs 
now with Fedora or Red Hat Enterprise Linux, so attempting to find it 
there by default on every bootup is wrong.  

To turn it around, what is the possible value in also probing the 
initramfs?  Does anyone out there load policy from it with systemd?

  

[-- Attachment #2: Type: text/html, Size: 1233 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [systemd-devel] [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 18:17   ` Colin Walters
@ 2014-02-20 18:36     ` Lennart Poettering
  2014-02-20 18:47       ` Colin Walters
  2014-02-20 18:50       ` Eric Paris
  2014-02-20 18:51     ` Stephen Smalley
  1 sibling, 2 replies; 15+ messages in thread
From: Lennart Poettering @ 2014-02-20 18:36 UTC (permalink / raw)
  To: Colin Walters; +Cc: systemd Mailing List, Stephen Smalley, SELinux-NSA

On Thu, 20.02.14 18:17, Colin Walters (walters@verbum.org) wrote:

Hmm, maybe a simple check access("/etc/selinux/", F_OK) would be enough?
There's no point in trying to initialized SELinux if that dir does not
exist, right? Then we could simply bypass the whole thing...

> On Thu, Feb 20, 2014 at 1:06 PM, Stephen Smalley <sds@tycho.nsa.gov>
> wrote:
> >
> >Wouldn't it be better (and more correct) to probe both the
> >initramfs and
> >the real root, and if neither one can load policy successfully and
> >enforcing=1, then halt?
> >
> So you're saying we should handle -ENOENT specially in the
> initramfs?  Something like being sure we preserve errno and
> returning it to the caller of selinux_init_load_policy()?  That
> would introduce a subtle version dependency.
> 
> Or alternatively, just try in the initramfs, ignore any errors, and
> only abort if we also fail to load in the real root?
> 
> I think both of these (particularly the second) are worse than my
> patch - we don't (to my knowledge) support putting policy in the
> initramfs now with Fedora or Red Hat Enterprise Linux, so attempting
> to find it there by default on every bootup is wrong.
> 
> To turn it around, what is the possible value in also probing the
> initramfs?  Does anyone out there load policy from it with systemd?
> 

> _______________________________________________
> systemd-devel mailing list
> systemd-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel



Lennart

-- 
Lennart Poettering, Red Hat

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [systemd-devel] [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 18:36     ` [systemd-devel] " Lennart Poettering
@ 2014-02-20 18:47       ` Colin Walters
  2014-02-20 18:50       ` Eric Paris
  1 sibling, 0 replies; 15+ messages in thread
From: Colin Walters @ 2014-02-20 18:47 UTC (permalink / raw)
  To: Lennart Poettering; +Cc: systemd Mailing List, Stephen Smalley, SELinux-NSA

[-- Attachment #1: Type: text/plain, Size: 933 bytes --]

On Thu, Feb 20, 2014 at 1:36 PM, Lennart Poettering 
<lennart@poettering.net> wrote:
> On Thu, 20.02.14 18:17, Colin Walters (walters@verbum.org) wrote:
> 
> Hmm, maybe a simple check access("/etc/selinux/", F_OK) would be 
> enough?
> There's no point in trying to initialized SELinux if that dir does not
> exist, right? Then we could simply bypass the whole thing...
> 

Beyond what Eric said, I also think that libselinux should continue to 
contain all of the key logic for whether or not SELinux is enabled and 
how to behave.

The current *API* seems OK in having the two return values of an error 
code and an enforcing flag.

The only thing libselinux can't know is:
1) Whether we're inside an initramfs right now
2) Whether or not the OS vendor expects policy to be found in the real 
root or the initramfs

So those bits of logic make sense to me in systemd, although there is 
an argument for #2 living in libselinux.




[-- Attachment #2: Type: text/html, Size: 1160 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [systemd-devel] [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 18:36     ` [systemd-devel] " Lennart Poettering
  2014-02-20 18:47       ` Colin Walters
@ 2014-02-20 18:50       ` Eric Paris
  2014-02-20 19:26         ` Lennart Poettering
  1 sibling, 1 reply; 15+ messages in thread
From: Eric Paris @ 2014-02-20 18:50 UTC (permalink / raw)
  To: Lennart Poettering; +Cc: Stephen Smalley, systemd Mailing List, SELinux-NSA

Not really.  If it doesn't exist on the final root fs and I put
enforcing=1 on the command line, I expect the box to
panic/fail/die/whatever....

On Thu, Feb 20, 2014 at 1:36 PM, Lennart Poettering
<lennart@poettering.net> wrote:
> On Thu, 20.02.14 18:17, Colin Walters (walters@verbum.org) wrote:
>
> Hmm, maybe a simple check access("/etc/selinux/", F_OK) would be enough?
> There's no point in trying to initialized SELinux if that dir does not
> exist, right? Then we could simply bypass the whole thing...
>
>> On Thu, Feb 20, 2014 at 1:06 PM, Stephen Smalley <sds@tycho.nsa.gov>
>> wrote:
>> >
>> >Wouldn't it be better (and more correct) to probe both the
>> >initramfs and
>> >the real root, and if neither one can load policy successfully and
>> >enforcing=1, then halt?
>> >
>> So you're saying we should handle -ENOENT specially in the
>> initramfs?  Something like being sure we preserve errno and
>> returning it to the caller of selinux_init_load_policy()?  That
>> would introduce a subtle version dependency.
>>
>> Or alternatively, just try in the initramfs, ignore any errors, and
>> only abort if we also fail to load in the real root?
>>
>> I think both of these (particularly the second) are worse than my
>> patch - we don't (to my knowledge) support putting policy in the
>> initramfs now with Fedora or Red Hat Enterprise Linux, so attempting
>> to find it there by default on every bootup is wrong.
>>
>> To turn it around, what is the possible value in also probing the
>> initramfs?  Does anyone out there load policy from it with systemd?
>>
>
>> _______________________________________________
>> systemd-devel mailing list
>> systemd-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
>
>
>
> Lennart
>
> --
> Lennart Poettering, Red Hat
> _______________________________________________
> Selinux mailing list
> Selinux@tycho.nsa.gov
> To unsubscribe, send email to Selinux-leave@tycho.nsa.gov.
> To get help, send an email containing "help" to Selinux-request@tycho.nsa.gov.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 18:17   ` Colin Walters
  2014-02-20 18:36     ` [systemd-devel] " Lennart Poettering
@ 2014-02-20 18:51     ` Stephen Smalley
  1 sibling, 0 replies; 15+ messages in thread
From: Stephen Smalley @ 2014-02-20 18:51 UTC (permalink / raw)
  To: Colin Walters; +Cc: systemd Mailing List, SELinux-NSA

On 02/20/2014 01:17 PM, Colin Walters wrote:
> On Thu, Feb 20, 2014 at 1:06 PM, Stephen Smalley <sds@tycho.nsa.gov> wrote:
>>
>> Wouldn't it be better (and more correct) to probe both the initramfs and
>> the real root, and if neither one can load policy successfully and
>> enforcing=1, then halt?
>>
> So you're saying we should handle -ENOENT specially in the initramfs? 
> Something like being sure we preserve errno and returning it to the
> caller of selinux_init_load_policy()?  That would introduce a subtle
> version dependency.
> 
> Or alternatively, just try in the initramfs, ignore any errors, and only
> abort if we also fail to load in the real root?
> 
> I think both of these (particularly the second) are worse than my patch
> - we don't (to my knowledge) support putting policy in the initramfs now
> with Fedora or Red Hat Enterprise Linux, so attempting to find it there
> by default on every bootup is wrong. 
> To turn it around, what is the possible value in also probing the
> initramfs?  Does anyone out there load policy from it with systemd?

Ok, I guess when you put it that way...

The only cases I know of where policy is loaded from initramfs are
embedded Linux and Android, neither of which are using systemd to my
knowledge, and both of which have custom policy loading logic anyway.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [systemd-devel] [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 18:50       ` Eric Paris
@ 2014-02-20 19:26         ` Lennart Poettering
  2014-02-20 19:27           ` Eric Paris
  0 siblings, 1 reply; 15+ messages in thread
From: Lennart Poettering @ 2014-02-20 19:26 UTC (permalink / raw)
  To: Eric Paris; +Cc: Stephen Smalley, systemd Mailing List, SELinux-NSA

On Thu, 20.02.14 13:50, Eric Paris (eparis@parisplace.org) wrote:

> Not really.  If it doesn't exist on the final root fs and I put
> enforcing=1 on the command line, I expect the box to
> panic/fail/die/whatever....

OK, then maybe check "!in_initrd() || access("/etc/selinux/", F_OK) >= 0"? 

Lennart

-- 
Lennart Poettering, Red Hat

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [systemd-devel] [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 19:26         ` Lennart Poettering
@ 2014-02-20 19:27           ` Eric Paris
  2014-02-20 19:45             ` Daniel J Walsh
  0 siblings, 1 reply; 15+ messages in thread
From: Eric Paris @ 2014-02-20 19:27 UTC (permalink / raw)
  To: Lennart Poettering; +Cc: Stephen Smalley, systemd Mailing List, SELinux-NSA

I like it, if it's reasonable/possible

On Thu, Feb 20, 2014 at 2:26 PM, Lennart Poettering
<lennart@poettering.net> wrote:
> On Thu, 20.02.14 13:50, Eric Paris (eparis@parisplace.org) wrote:
>
>> Not really.  If it doesn't exist on the final root fs and I put
>> enforcing=1 on the command line, I expect the box to
>> panic/fail/die/whatever....
>
> OK, then maybe check "!in_initrd() || access("/etc/selinux/", F_OK) >= 0"?
>
> Lennart
>
> --
> Lennart Poettering, Red Hat

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [systemd-devel] [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 19:27           ` Eric Paris
@ 2014-02-20 19:45             ` Daniel J Walsh
  2014-02-20 20:52               ` Colin Walters
  0 siblings, 1 reply; 15+ messages in thread
From: Daniel J Walsh @ 2014-02-20 19:45 UTC (permalink / raw)
  To: Eric Paris, Lennart Poettering
  Cc: systemd Mailing List, Stephen Smalley, SELinux-NSA

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 02/20/2014 02:27 PM, Eric Paris wrote:
> I like it, if it's reasonable/possible
> 
> On Thu, Feb 20, 2014 at 2:26 PM, Lennart Poettering 
> <lennart@poettering.net> wrote:
>> On Thu, 20.02.14 13:50, Eric Paris (eparis@parisplace.org) wrote:
>> 
>>> Not really.  If it doesn't exist on the final root fs and I put 
>>> enforcing=1 on the command line, I expect the box to 
>>> panic/fail/die/whatever....
>> 
>> OK, then maybe check "!in_initrd() || access("/etc/selinux/", F_OK) >=
>> 0"?
>> 
>> Lennart
>> 
>> -- Lennart Poettering, Red Hat
> _______________________________________________ Selinux mailing list 
> Selinux@tycho.nsa.gov To unsubscribe, send email to
> Selinux-leave@tycho.nsa.gov. To get help, send an email containing "help"
> to Selinux-request@tycho.nsa.gov.
You mean

"!in_initrd() || access(selinux_path(), F_OK) >= 0"?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iEYEARECAAYFAlMGW1AACgkQrlYvE4MpobOeUgCg3YoRWatuabfOsAGLD4p09QVo
PYMAn3hDTBy4ePCPy/jORYlE+KGotSxE
=kkZx
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [systemd-devel] [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 19:45             ` Daniel J Walsh
@ 2014-02-20 20:52               ` Colin Walters
  2014-02-20 21:10                 ` Eric Paris
  0 siblings, 1 reply; 15+ messages in thread
From: Colin Walters @ 2014-02-20 20:52 UTC (permalink / raw)
  To: systemd Mailing List, SELinux-NSA

[-- Attachment #1: Type: text/plain, Size: 644 bytes --]

On Thu, Feb 20, 2014 at 2:45 PM, Daniel J Walsh <dwalsh@redhat.com> 
wrote:
>> 
>> 
> You mean
> 
> "!in_initrd() || access(selinux_path(), F_OK) >= 0"?
> 

I don't think so - that would mean we would silently continue if 
enforcing=1, but we happen to not find a policy on disk.  Right?

I think my patch is better than this - systemd will attempt to load 
policy from *only* the real root (not the initramfs), using the exact 
same logic as is in libselinux currently.

For example, it would allow explicitly specifying enforcing=1 on the 
kernel command line, and that would continue to cause an explicit 
failure if policy is not found.




[-- Attachment #2: Type: text/html, Size: 860 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [systemd-devel] [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 20:52               ` Colin Walters
@ 2014-02-20 21:10                 ` Eric Paris
  2014-02-20 21:21                   ` Colin Walters
  0 siblings, 1 reply; 15+ messages in thread
From: Eric Paris @ 2014-02-20 21:10 UTC (permalink / raw)
  To: Colin Walters; +Cc: systemd Mailing List, SELinux-NSA

I think the idea was

if we are not in the initrd - try to load policy
if we are in the initrd and we find selinux_path() - try to load policy

Thus embeded/thin who put everything inside the initrd will work (and
the kernel enforce=1 will mean what is should)
And where we don't put anything inside the initrd will still be
correct since we'll try to load no matter what in the real root

On Thu, Feb 20, 2014 at 3:52 PM, Colin Walters <walters@verbum.org> wrote:
> On Thu, Feb 20, 2014 at 2:45 PM, Daniel J Walsh <dwalsh@redhat.com> wrote:
>
> You mean "!in_initrd() || access(selinux_path(), F_OK) >= 0"?
>
>
> I don't think so - that would mean we would silently continue if
> enforcing=1, but we happen to not find a policy on disk.  Right?
>
> I think my patch is better than this - systemd will attempt to load policy
> from *only* the real root (not the initramfs), using the exact same logic as
> is in libselinux currently.
>
> For example, it would allow explicitly specifying enforcing=1 on the kernel
> command line, and that would continue to cause an explicit failure if policy
> is not found.
>
>
>
> _______________________________________________
> Selinux mailing list
> Selinux@tycho.nsa.gov
> To unsubscribe, send email to Selinux-leave@tycho.nsa.gov.
> To get help, send an email containing "help" to
> Selinux-request@tycho.nsa.gov.
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [systemd-devel] [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 21:10                 ` Eric Paris
@ 2014-02-20 21:21                   ` Colin Walters
  2014-02-20 23:44                     ` Colin Walters
  0 siblings, 1 reply; 15+ messages in thread
From: Colin Walters @ 2014-02-20 21:21 UTC (permalink / raw)
  To: Eric Paris; +Cc: systemd Mailing List, SELinux-NSA

[-- Attachment #1: Type: text/plain, Size: 713 bytes --]



On Thu, Feb 20, 2014 at 4:10 PM, Eric Paris <eparis@parisplace.org> 
wrote:
> I think the idea was
> 
> if we are not in the initrd - try to load policy
> if we are in the initrd and we find selinux_path() - try to load 
> policy
> 
> Thus embeded/thin who put everything inside the initrd will work (and
> the kernel enforce=1 will mean what is should)
> And where we don't put anything inside the initrd will still be
> correct since we'll try to load no matter what in the real root
> 
I guess then as long as we don't attempt to load policy again if we 
already have done so in the initrd - and yes, systemd already has logic 
of this form inside selinux_setup().

I'm testing this suggested patch now.





[-- Attachment #2: Type: text/html, Size: 879 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [systemd-devel] [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 21:21                   ` Colin Walters
@ 2014-02-20 23:44                     ` Colin Walters
  2014-02-21  2:33                       ` Lennart Poettering
  0 siblings, 1 reply; 15+ messages in thread
From: Colin Walters @ 2014-02-20 23:44 UTC (permalink / raw)
  To: Eric Paris; +Cc: systemd Mailing List, SELinux-NSA


[-- Attachment #1.1: Type: text/plain, Size: 267 bytes --]

On Thu, Feb 20, 2014 at 4:21 PM, Colin Walters <walters@verbum.org> 
wrote:
> 
> I'm testing this suggested patch now.
> 
I tweaked the suggestion a bit because the selinux_path() API call made 
the most sense inside selinux-setup.c.  Attached patch works for me.




[-- Attachment #1.2: Type: text/html, Size: 375 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-selinux-Don-t-attempt-to-load-policy-in-initramfs-if.patch --]
[-- Type: text/x-patch, Size: 3386 bytes --]

>From ae5f54b4d34320528db8fd1bb24ab7479d081594 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Thu, 20 Feb 2014 10:15:10 -0500
Subject: [PATCH] selinux: Don't attempt to load policy in initramfs if it
 doesn't exist

Currently on at least Fedora, SELinux policy does not come in the
initramfs.  systemd will attempt to load *both* in the initramfs and
in the real root.

Now, the selinux_init_load_policy() API has a regular error return
value, as well as an "enforcing" boolean.  To determine enforcing
state, it looks for /etc/selinux/config as well as the presence of
"enforcing=" on the kernel command line.

Ordinarily, neither of those exist in the initramfs, so it will return
"unknown" for enforcing, and systemd will simply ignore the failure to
load policy.

Then later after we switch to the real root, we have the config file,
and all will work properly.

Except...this all blows up if someone explicitly specifies enforcing=1
on the kernel command line.  Then systemd will fail to load the
nonexistent policy in the initramfs and freeze.

This patch tweaks the logic so we attempt to load policy from the
initramfs only if we see it exists.  We always attempt to load from
the real root - but selinux_setup() is a noop if policy is already
loaded, so the case of "policy successfully loaded in initramfs, not
in the real root" will work.

Lots-of-very-painful-debugging-by: Colin Walters <walters@verbum.org>
---
 src/core/main.c          | 2 +-
 src/core/selinux-setup.c | 9 ++++++++-
 src/core/selinux-setup.h | 2 +-
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/core/main.c b/src/core/main.c
index 58c3a9e..49f237a 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1296,7 +1296,7 @@ int main(int argc, char *argv[]) {
 
                 if (!skip_setup) {
                         mount_setup_early();
-                        if (selinux_setup(&loaded_policy) < 0)
+                        if (selinux_setup(in_initrd(), &loaded_policy) < 0)
                                 goto finish;
                         if (ima_setup() < 0)
                                 goto finish;
diff --git a/src/core/selinux-setup.c b/src/core/selinux-setup.c
index 7a32ed5..ee0ac32 100644
--- a/src/core/selinux-setup.c
+++ b/src/core/selinux-setup.c
@@ -43,7 +43,7 @@ static int null_log(int type, const char *fmt, ...) {
 }
 #endif
 
-int selinux_setup(bool *loaded_policy) {
+int selinux_setup(bool in_initrd, bool *loaded_policy) {
 
 #ifdef HAVE_SELINUX
        int enforce = 0;
@@ -54,6 +54,13 @@ int selinux_setup(bool *loaded_policy) {
 
        assert(loaded_policy);
 
+       /* Don't load policy in the initrd if we don't appear to have
+        * it.  For the real root, we check below if we've already
+        * loaded policy, and return gracefully.
+        */
+       if (in_initrd && access(selinux_path(), F_OK) == -1)
+               return 0;
+
        /* Turn off all of SELinux' own logging, we want to do that */
        cb.func_log = null_log;
        selinux_set_callback(SELINUX_CB_LOG, cb);
diff --git a/src/core/selinux-setup.h b/src/core/selinux-setup.h
index 39e2bc2..9291144 100644
--- a/src/core/selinux-setup.h
+++ b/src/core/selinux-setup.h
@@ -23,4 +23,4 @@
 
 #include <stdbool.h>
 
-int selinux_setup(bool *loaded_policy);
+int selinux_setup(bool in_initrd, bool *loaded_policy);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [systemd-devel] [PATCH] selinux: Only attempt to load policy exactly once, in the real root
  2014-02-20 23:44                     ` Colin Walters
@ 2014-02-21  2:33                       ` Lennart Poettering
  0 siblings, 0 replies; 15+ messages in thread
From: Lennart Poettering @ 2014-02-21  2:33 UTC (permalink / raw)
  To: Colin Walters; +Cc: systemd Mailing List, SELinux-NSA

On Thu, 20.02.14 23:44, Colin Walters (walters@verbum.org) wrote:

> On Thu, Feb 20, 2014 at 4:21 PM, Colin Walters <walters@verbum.org>
> wrote:
> >
> >I'm testing this suggested patch now.
> >
> I tweaked the suggestion a bit because the selinux_path() API call
> made the most sense inside selinux-setup.c.  Attached patch works
> for me.

It's actually even easier than this patch, as in_initrd() is a normal
exported function, we can call it directly from selinux_setup(). I have
made that change to your patch and commited it. Please test!

Thanks!

Lennart

-- 
Lennart Poettering, Red Hat

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2014-02-21  2:33 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-20 15:42 [PATCH] selinux: Only attempt to load policy exactly once, in the real root Colin Walters
2014-02-20 18:06 ` Stephen Smalley
2014-02-20 18:17   ` Colin Walters
2014-02-20 18:36     ` [systemd-devel] " Lennart Poettering
2014-02-20 18:47       ` Colin Walters
2014-02-20 18:50       ` Eric Paris
2014-02-20 19:26         ` Lennart Poettering
2014-02-20 19:27           ` Eric Paris
2014-02-20 19:45             ` Daniel J Walsh
2014-02-20 20:52               ` Colin Walters
2014-02-20 21:10                 ` Eric Paris
2014-02-20 21:21                   ` Colin Walters
2014-02-20 23:44                     ` Colin Walters
2014-02-21  2:33                       ` Lennart Poettering
2014-02-20 18:51     ` Stephen Smalley

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.