Red Hat Bugzilla – Bug 189191
Can't load SELinux policy modules with a read-only filesystem
Last modified: 2014-03-16 22:59:26 EDT
Description of problem:
Heck, you can't even list the active modules. Looks like, among other things,
it's trying to create lock files in /etc.
This can be worked around in stateless by 'installing' the module first. But it's
still awfully odd.
Steven, shouldn't load_policy succeed if /etc read only?
load_policy works fine in that case. The problem is that semodule ->
libsemanage manages the module store under /etc/selinux/$SELINUXTYPE/modules,
and that includes lock files plus the modules themselves and the generated
policy. /etc has to be writable for policy updates (which is what installing a
policy module is). Or we have to the policy module store elsewhere, but that is
a big PITA at this point.
So, I suspect part of this was my unfamiliarity with the module process;
semodule -i is actually the combination of 'install the policy in the place
where it's loaded from, and load it'; the loading itself can be done read-only,
provided it's already there.
So, what I'd suggest is:
1) is there a way to load the binary policy module without copying it to /etc/XXXX?
2) semodule -l should at least still work when read-only.
"Loading" a policy module requires linking it with all other policy modules
(including the base module) and then expanding the linked policy to a kernel
binary policy file, then loading that kernel binary policy file.
At present, that requires going through libsemanage (which is what semodule
does) and manipulating the module store, yielding a final generated kernel
policy in the standard location which is then loaded by load_policy.
There are development tools included in policycoreutils (semodule_link,
semodule_expand) that can be used to manually link and expand modular policy to
kernel policy in a separate location, but that is really just for
development/debug purposes, and load_policy presently will only load policy from
the standard location under /etc/selinux/... (see prior discussions about moving
policy loading logic into libselinux and selinux_mkload_policy interface used by
load_policy these days).
So the short answer is no. If /etc is going to be rdonly (and we can't get a
separate rw mount on /etc/selinux), then /etc/selinux likely needs to be
relocated or at least transparently relocatable for the tools, which suggests a
patch to libselinux to use an alternate location if defined, e.g. via
environment variable. Although you'd likely want that scrubbed if libc secure
mode was enabled.
1) No, the modules must be protected and preserved in the store. If the modules
are elsewhere they could get replaced outside of semodule and the next policy
change would pull in a different policy.
2) We need reader locks on the store to prevent a reader from getting a new
policy in mid-read.
My suggestion would be to move the whole /etc/selinux directory somewhere else
and bind mount to /etc/selinux. Be sure the labels are correct afterward.
(semanage fcontext to make sure they are preserved)
Did we decide what we want to do here? I pointed out in email that checking the
filesystem for EROFS isn't totally safe (since the filesystem can be remounted
rw in the middle of an operation and the lock won't be held) but if that is an
acceptable risk we can put the check in there..
Can't we just use the readonly lock?
IIRC flock works fine on a readonly filesystem so we just need to make sure we
aren't trying to open files O_RW if the connection is read only. I'll take a
look at this as soon as I can, unless someone else gets around to it first.
This is fixed in upstream libsemanage svn revision 33
Fixed in libsemanage-1.6.12-1