All of lore.kernel.org
 help / color / mirror / Atom feed
* SELinux policy updates in a post-%post world
@ 2014-03-25  1:54 Colin Walters
  2014-03-25 17:13 ` Stephen Smalley
  0 siblings, 1 reply; 3+ messages in thread
From: Colin Walters @ 2014-03-25  1:54 UTC (permalink / raw)
  To: selinux

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

Hi,

I mentioned OSTree earlier here.  An issue came up with the SELinux 
integration; to understand it, let me describe how OSTree upgrades work:

1) We perform an rsync-like[1] process to a *new* chroot
2) A "basic" configuration merge is done - we take the new /etc 
defaults, and apply any modified files on top

Note that the policy.19 file is in /etc.

Crucially, there is at present no %post/postinst type functionality.  
This is a dramatic increase in reliability over traditional packages.  
No shell script run as root copy/pasted or just copied from elsewhere 
appended to everything.

For things like /usr/lib/ld.so.cache which is just a cache, this works 
fine because it's just referencing things in /usr/lib - it's all 
precomputed on the compose server.

Now, at least the Fedora selinux-policy has a %post that runs "semodule 
-B" which recompiles the policy (if the client machine has modified it 
locally).

Currently with OSTree, what will happen is it will notice the policy.19 
file is a modified file in /etc, and simply carry it forward.  In other 
words, updates to the base policy have no effect once the admin has 
modified it locally.

Administrators *can* rerun "semodule -B" manually after booting into 
the new root to recompile.

Why can't I just add a %post concept to OSTree?  Well, I could.  But 
I'd like to try as hard as conceivably possible to avoid it, and even 
then only do it where all other avenues are exhausted.  For one thing, 
it would break the ability to do completely offline updates (e.g. open 
up a VM guest disk from the host, and update it).  This ability is 
presently used to great effect in the testing system.

The primary alternative to %post is a "dynamic merge".  For example, 
systemd has a design where the default unit files are in 
/usr/lib/system, and then "dropins" can customize them in 
/etc/systemd/system.  On boot, it unions the two.

Similarly, I added /usr/lib/passwd in addition to /etc/passwd:
https://sourceware.org/bugzilla/show_bug.cgi?id=16142

However...I'm uncertain about doing this for SELinux policy.  The 
policy load happens very early in userspace setup and it's a complex 
task.

One option is to recompile the policy if we can (we're doing an upgrade 
from inside a running system, just chroot to new deployment and rerun 
semodule), and throw an error if we can't do it (the offline upgrade 
case).  The latter would only occur when a machine has a modified 
policy, which doesn't happen for my testing system.

Any other ideas?

[1] It doesn't share any code with rsync, but the details are 
irrelevant for this purpose

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

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

* Re: SELinux policy updates in a post-%post world
  2014-03-25  1:54 SELinux policy updates in a post-%post world Colin Walters
@ 2014-03-25 17:13 ` Stephen Smalley
  2014-03-25 21:17   ` Colin Walters
  0 siblings, 1 reply; 3+ messages in thread
From: Stephen Smalley @ 2014-03-25 17:13 UTC (permalink / raw)
  To: Colin Walters, selinux

On 03/24/2014 09:54 PM, Colin Walters wrote:
> Hi,
> 
> I mentioned OSTree earlier here.  An issue came up with the SELinux
> integration; to understand it, let me describe how OSTree upgrades work:
> 
> 1) We perform an rsync-like[1] process to a *new* chroot
> 2) A "basic" configuration merge is done - we take the new /etc
> defaults, and apply any modified files on top
> 
> Note that the policy.19 file is in /etc.
> 
> Crucially, there is at present no %post/postinst type functionality.
>  This is a dramatic increase in reliability over traditional packages.
>  No shell script run as root copy/pasted or just copied from elsewhere
> appended to everything.
> 
> For things like /usr/lib/ld.so.cache which is just a cache, this works
> fine because it's just referencing things in /usr/lib - it's all
> precomputed on the compose server.
> 
> Now, at least the Fedora selinux-policy has a %post that runs "semodule
> -B" which recompiles the policy (if the client machine has modified it
> locally).
> 
> Currently with OSTree, what will happen is it will notice the policy.19
> file is a modified file in /etc, and simply carry it forward.  In other
> words, updates to the base policy have no effect once the admin has
> modified it locally.
> 
> Administrators *can* rerun "semodule -B" manually after booting into the
> new root to recompile.
> 
> Why can't I just add a %post concept to OSTree?  Well, I could.  But I'd
> like to try as hard as conceivably possible to avoid it, and even then
> only do it where all other avenues are exhausted.  For one thing, it
> would break the ability to do completely offline updates (e.g. open up a
> VM guest disk from the host, and update it).  This ability is presently
> used to great effect in the testing system.
> 
> The primary alternative to %post is a "dynamic merge".  For example,
> systemd has a design where the default unit files are in
> /usr/lib/system, and then "dropins" can customize them in
> /etc/systemd/system.  On boot, it unions the two.
> 
> Similarly, I added /usr/lib/passwd in addition to /etc/passwd:
> https://sourceware.org/bugzilla/show_bug.cgi?id=16142
> 
> However...I'm uncertain about doing this for SELinux policy.  The policy
> load happens very early in userspace setup and it's a complex task.
> 
> One option is to recompile the policy if we can (we're doing an upgrade
> from inside a running system, just chroot to new deployment and rerun
> semodule), and throw an error if we can't do it (the offline upgrade
> case).  The latter would only occur when a machine has a modified
> policy, which doesn't happen for my testing system.
> 
> Any other ideas?

Can you explain when/why you cannot run semodule -B?  As long as you
also pass it -n and -s <store-name> and possibly -p <rootpath>, it
should work and should not affect the running system until reboot or
next policy load.

Effectively semodule -B is performing a merge, by merging any local
policy customizations into the updated policy.  You do want the merge
because the updated policy may include changes required for the updated
system components, while the local customizations may be required for
system operation (e.g. local file_contexts entries, boolean settings,
login mappings, added allow rules for third party software or
non-standard configurations), so using either just the modified policy
from before the upgrade or just the unmodified updated policy could
leave the system in a non-functional state.

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

* Re: SELinux policy updates in a post-%post world
  2014-03-25 17:13 ` Stephen Smalley
@ 2014-03-25 21:17   ` Colin Walters
  0 siblings, 0 replies; 3+ messages in thread
From: Colin Walters @ 2014-03-25 21:17 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux

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



On Tue, Mar 25, 2014 at 1:13 PM, Stephen Smalley <sds@tycho.nsa.gov> 
wrote:
> 
> Can you explain when/why you cannot run semodule -B?  As long as you
> also pass it -n and -s <store-name> and possibly -p <rootpath>, it
> should work and should not affect the running system until reboot or
> next policy load.

Right.  The first reason is at the moment I have an update system that 
*has no %post at all*.  It's much less flexible than traditional 
packages, but is much more reliable.

I have two high level concerns:
1) If I'm running arbitrary code, I want it to be started by systemd 
and ensure any log messages from it go to the journal, any error code 
is tracked, any processes started are properly cleaned up, etc.  Were I 
to add a %post type thing I'd likely use systemd-nspawn for this to 
ensure that /proc is mounted and all other requirements are met.

On the other hand, if it's just SELinux for now I may just commit 
support into the ostree core to recompile the policy in the new root 
directly from the main process and not fork off any other tool.

2) External tools may not match the "fdatasync policy".  Looking at the 
implementation of semanage_direct_commit() in 
selinux/libsemanage/src/direct_api.c, we create empty files, but don't 
open the parent directory fd and sync it.  Similarly, 
semanage_write_policydb() appears to just use fclose() and does not 
attempt to fdatasync() the policy file on disk.

This has been a real world problem with other triggers like 
gtk-update-icon-cache.  RPM is pretty careful to fdatasync() files it 
writes to disk.  But until:
https://git.gnome.org/browse/gtk+/commit/?id=6c6b49392629a8ee2facafb66c8867a49a3e9036
if you pulled the power after RPM said a "transaction" was complete, 
you could end up with a corrupted icon cache.

Now I admit, right now in OSTree I am simply doing a global sync() 
before swapping the bootloader configuration:
https://git.gnome.org/browse/ostree/tree/src/libostree/ostree-sysroot-deploy.c#n692

But that's a short term hack since sync() doesn't return errors, and it 
forces a flush of *everything* which can be a major performance hit.

On the other hand, there are cases where we *don't* want to 
fdatasync(), like constructing mock/pbuilder type build roots.  Some 
discussion here:
https://bugs.freedesktop.org/show_bug.cgi?id=70366

> Effectively semodule -B is performing a merge, by merging any local
> policy customizations into the updated policy.  You do want the merge
> because the updated policy may include changes required for the 
> updated
> system components, while the local customizations may be required for
> system operation (e.g. local file_contexts entries, boolean settings,
> login mappings, added allow rules for third party software or
> non-standard configurations), so using either just the modified policy
> from before the upgrade or just the unmodified updated policy could
> leave the system in a non-functional state.

Right, absolutely.  I want policy updates to work with local 
configuration as they do with traditional packages.  I also want 
upgrades to be fully atomic.  The goal is to do both =)



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

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

end of thread, other threads:[~2014-03-25 21:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-25  1:54 SELinux policy updates in a post-%post world Colin Walters
2014-03-25 17:13 ` Stephen Smalley
2014-03-25 21:17   ` Colin Walters

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.